You may want to have a look at mitmproxy. This allows you to intercept and modify http(s) traffic, which may or may not be what you need, but it also has tools like mitmdump that just dump what's going over the connection.
Mitmproxy also has instructions about setting up the linux tcp stack using iptables to redirect connections. I guess this is the main part of what you're trying to achieve.
In your setup, the easiest thing you could do is probably create a virtual machine using virtualbox, running the client within the machine, using iptables inside the machine to redirect server connections to your host, and run the proxy on the host.
The advantage of using a virtual machine is that whatever you install/configure on your VM won't interfere with your host, where you may not want to mess with the network to reduce the risk of breaking other things, and you can create a snapshot and go back to it of you break something and don't remember what exactly you've done.
Then, on the VM, do something like
iptables -t nat -A OUTPUT -p tcp --dport 1234 -j DNAT --to-destination 1.2.3.4:1234
to redirect all traffic from the client, independent from target ip, to the host (assuming the host is 1.2.3.4). The, on the host, write a program to listen on port 1234, dump all data, and pass through to real.server.ip:1234. This way, you don't have to mess with the IP configuration of the host.
If you don't want to use a VM, you could also use
iptables -t nat -A OUTPUT -p tcp --dport 1234 -j DNAT --to-destination 127.0.0.1:1234
iptables -t nat -A OUTPUT -p tcp --dport 1235 -j DNAT --to-destination :1234
and have your program listen on port 1234, and connect to 1235 on the real server. The second iptables entry will redirect this to 1234 again, and use the IP the program requested, since you just used a port without an IP in the --to-destination
argument. Your client (that uses port 1234) always gets redirected to localhost, and the proxy, that connects to 1235, will get redirected to 1234. Obviously, the order of iptables commands is important here.
You can use the real server ip or name as well, of course:
iptables -t nat -A OUTPUT -p tcp --dport 1235 -j DNAT --to-destination 192.168.17.135:1234
iptables -t nat -A OUTPUT -p tcp --dport 1235 -j DNAT --to-destination real.server.name:1234
but note that real.server.name
gets resolved the moment you start the iptables command, not when the packet gets sent. So, if your real.server.address changes later, for example if it's behind a dynamic IP, you'll have to remove the iptables entry and create a new one.
And to minimize impact on your machine, where you might have an unrelated program connect to an unrelated server on port 1235, you might want to restrict changing the port to one particular server only:
iptables -t nat -A OUTPUT -p tcp --dest 192.168.17.135 --dport 1235 -j DNAT --to-destination 192.168.17.135:1234