I have a requirement to implement a transparent proxy. One of the building blocks is the ability to send a packet out from the proxy server with the source IP of the client. Loosely referred as spoofing the client IP.
When I experimented with test virtual machines, by crafting a packet with hping3, the packet does not make it to the destination. It seems to be dropped at the gateway. In my experiment, both source and destination IPs are private IPs to keep the experiment simple.
Experiment set up:
Vm1: 10.128.0.2, vm2: 10.128.0.3, vm3: 10.128.0.4. They are all in the same VPC.
Send a packet from vm2 to vm3 with source IP as 10.128.0.2.
Any thoughts/ideas would be appreciated.
Solved! Go to Solution.
I figured out how to do this. I am sharing my finding hoping it will be useful for someone.
The bottom line is that when a VM is created it should be marked as a forwarding VM using the "IP Forward" flag. When this flag is checked, the VM is allowed to send packets with source IPs that are not assigned to the VM. This flag cannot be modified after the VM is created from the console. But this flag can be modified using gcloud CLI.
From the console:
When you create the VM, go to "Advanced Options" section at the bottom of the screen. Click on "Networking", then check the "IP Forwarding" check box.
From the gcloud CLI:
First export the configuration of the VM instance (instance1 is the name of the instance).
gcloud compute instances export --zone us-central1-a --destination /tmp/instance1.yml instance1
Then edit the /tmp/instance1.yml file and set "canIpForward" value to be true.
Now you can update the VM using the following command:
gcloud compute instances update-from-file --zone us-central1-a --source /tmp/instance1.yml instance1
Thats it.
With this setting turned on, you should be able to send packets with source IPs that are not assigned to the VM.
I would check that you have a firewall rule that allows traffic in the VPC you are using. By default VPC has an implied firewall rule that denies all ingress traffic, so without adding an additional rule the firewall will stop traffic.
Here's a firewall rule example that you can use to allow in VPC traffic.
Does your firewall rule also allow all protocol types, or at least the ones you are using in your test? Otherwise the rule looks good to me.
Something else to try could be to use Connectivity Tests in the Cloud Console to rule out firewall rules as the issue here. If you try this share the outcome and I can recommend a few next steps.
Hi Qt,
I used the Connectivity Tests you shared to run the test and the tests pass. But the tests were run with a source IP of 10.128.0.3 (which is the true private IP of the VM), instead of the non-local IP 10.128.0.2 that I would like to test. There is no option to change this from the Connectivity Tests page.
From vm2 (10.128.0.3), I tried a different test instead: I used hping3 to crafted a SYN packet with source IP of 10.128.0.2 and dest IP 10.128.0.4 and send it. I can confirm in tcpdump that the packet is sent from vm2. But it was not delivered to 10.128.0.4.
I figured out how to do this. I am sharing my finding hoping it will be useful for someone.
The bottom line is that when a VM is created it should be marked as a forwarding VM using the "IP Forward" flag. When this flag is checked, the VM is allowed to send packets with source IPs that are not assigned to the VM. This flag cannot be modified after the VM is created from the console. But this flag can be modified using gcloud CLI.
From the console:
When you create the VM, go to "Advanced Options" section at the bottom of the screen. Click on "Networking", then check the "IP Forwarding" check box.
From the gcloud CLI:
First export the configuration of the VM instance (instance1 is the name of the instance).
gcloud compute instances export --zone us-central1-a --destination /tmp/instance1.yml instance1
Then edit the /tmp/instance1.yml file and set "canIpForward" value to be true.
Now you can update the VM using the following command:
gcloud compute instances update-from-file --zone us-central1-a --source /tmp/instance1.yml instance1
Thats it.
With this setting turned on, you should be able to send packets with source IPs that are not assigned to the VM.