Note, I can't use SSL termination at the load balancer, due to network security related issues.
The client IP I get is of course that of the load balancer. I know that the load balancer can't modify the HTTPS message without having my key, but is there another way to get the client IP address when load balancing with SSL, such as maybe just load balancing at the TCP level, or something?
In a short answer, you have to terminate the SSL at the load balancer if you want X-Forwarded-For to work.
Otherwise in a typical configuration with a "dumb" load balancer, the load balancer only acts as an intermediary between the VIP and the real IP - resulting in the load balancer's IPs showing up in the logs. The load balancer cannot insert a header if it cannot decrypt the traffic.
As for balancing TCP connections, that is essentially what you are doing if you're not terminating SSL at the load balancer.
It's possible that a NetScaler or some manner of proxy device could be configured to log requests by IP, but without the private key it would not be able to determine the specifics of the request such as the URI or request method.