Mesh and curve modifier.
Once set up, can travel along curve by displacing our dummy edge object
Having tried a method similar to @moonboots answer in writing a train addon found using the method outlined below kept the wheels on track (better if the curve is too tight nothing will help). This may not matter too much with a deforming object like a snake. However it only requires making one very simple mesh object, with vertex groups as targets for bone constraints.
Trying to place empties on the curve with offsets will cause the "train to derail" as the offset is looking at curve length rather than where the line segment next meets the curve. For example a unit circle radius 1, can hold a square with edge lengths sqrt(2)
each corner touches the circle. The arc length is p1 / 2
Trying to get the empty locations right on a complex curve is IMO too hard.
If a mesh is created and threaded onto a curve with a modifier the edge lengths are preserved.
Create a simple mesh as shown. With edges and verts emulating bones.
Here the mesh is moved 1 over for visual
Add a curve modifier to the mesh. I've made the mesh z up to cooncide with bones global orientation, so I track the mesh on curve using Z. The mesh can "run on the tracks" by animating its Z location property. Can switch tracks by changing this one modifier target
Next we add a copy location constraint of root bone to our mesh object, with base vertex group as a subtarget, and a track to constraint along the axis of bone "Y" to the next vertex group.
For all subsequent bones in chain add track to constraint to next vertex group.