Generally, it works like you described.
Important: Every client should have his own crosshair, right? that should not be visible to the other player?
I'll just assume that's what you want!
So you have to be carefull that all that code you wrote for selecting the enemy/object only runs the the local client, not on the server.
How do you do that?
When creating the crosshair as an entity, use ent_createlocal (...) !
This way, the entity is a local entity, and it's function is only executed on the system you run ent_createlocal on.
You still have to take care that ent_createlocal itself is run on the client that selects the target and wants to have the crosshair over it, but that's up to you.
if you are currently using ent_create for creating the crosshair, the following happens: the function you have given ent_create as an argument is started on the server, no matter where you execute ent_create.
Let's assume that this function is using "vec_set(my.x,targeted_ent.x);". But on the server, targeted_ent is not the same as on the client. It might move the crosshair somewhere where you don't see it, or you should be getting an "emtpy pointer" error.
Maybe you are using ent_create, but you are running "vec_set(my.x,targeted_ent.x);" on the client, though proc_client or something like it. Then, the crosshair is indeed set to the position of the targeted_ent, but the server does not know this. He still thinks that the crosshair is where you have created it, and sends this view to all the clients. He is always forcing the clients to see what he sees. Because of this, the crosshair does not follow the targeted_ent, no matter how often you call vec_set(..);. The server will always set it back to where he thinks the crosshair is.
Hope this helped you, ask me if some of the stuff I wrote wasn't clear enough.