Skip to content

Launch multiple sshuttle with different tproxy mark#565

Merged
brianmay merged 7 commits intosshuttle:masterfrom
samuelbernardolip:tproxy_mark_param
Dec 27, 2020
Merged

Launch multiple sshuttle with different tproxy mark#565
brianmay merged 7 commits intosshuttle:masterfrom
samuelbernardolip:tproxy_mark_param

Conversation

@samuelbernardolip
Copy link
Contributor

@samuelbernardolip samuelbernardolip commented Dec 6, 2020

This PR resolves issue #374

Add argument for tproxy mark and change code to receive this new parameter.
Coverage test only testing default case with mark='1' to allow passing tests. Needs further testing for new option, but didn't understand how firewall_setup method is being invoked (need help here).
Update documentation with new options.
Also update workflows and .gitignore for reference fork testing and development.

…proxy mark option to allow different network mapping.

Signed-off-by: Samuel Bernardo <samuel@lip.pt>
Signed-off-by: Samuel Bernardo <samuel@lip.pt>
Signed-off-by: Samuel Bernardo <samuel@lip.pt>
Signed-off-by: Samuel Bernardo <samuel@lip.pt>
Signed-off-by: Samuel Bernardo <samuel@lip.pt>
Signed-off-by: Samuel Bernardo <samuel@lip.pt>
Signed-off-by: Samuel Bernardo <samuel@lip.pt>
@brianmay
Copy link
Member

brianmay commented Dec 8, 2020

What help did you need regarding firewall_setup?

@samuelbernardolip
Copy link
Contributor Author

samuelbernardolip commented Dec 9, 2020

What help did you need regarding firewall_setup?

Understanding how firewall_setup is called from client.py.

This would be important to do the traceback for any issue and also improve the functional tests. As I could understand, I only found unit tests with mocks testing directly the methods. The code I added in this PR is already being tested with tproxy unit tests already available, but new feature is only being tested with default value.

I also need some guidance about the tests that need to be provided for the new option tmark.

@brianmay
Copy link
Member

brianmay commented Dec 9, 2020

The main() function creates a FirewallClient object:

fw = FirewallClient(method_name, sudo_pythonpath)

This in turn creates a forked process via sudo that runs the firewall code.

Later on, when we are connected via ssh, the main function, or rather the serverready subfunction of main calls:

fw.start()

This sends the required initialization commands to the firewall process. Including the ROUTES, NSLIST, PORTS, and GO.

When the firewall process sees all these commands, it will call method.setup_firewall one or twice depending on if IPv6 or IPv4 is configured.

https://github.com/sshuttle/sshuttle/blob/master/sshuttle/firewall.py#L210

Does this help?

@samuelbernardolip
Copy link
Contributor Author

This sends the required initialization commands to the firewall process. Including the ROUTES, NSLIST, PORTS, and GO.

When the firewall process sees all these commands, it will call method.setup_firewall one or twice depending on if IPv6 or IPv4 is configured.

https://github.com/sshuttle/sshuttle/blob/master/sshuttle/firewall.py#L210

Does this help?

Yes, thank you Brian. My doubt was there after fw.start().

To keep the interface for method.setup_firewall I didn't add the new tmark argument there. I'm doing maybe something nasty, because I only load it with fw.setup call and expect it to be there as a property in the created object.
The tmark tests passed because I check the property and if not defined I set the expected default value tmark='1'. Inside setup_firewall for tproxy method I do the following:
if self.firewall is None:
tmark = '1'
else:
tmark = self.firewall.tmark

Is this a good approach to add this argument that is only necessary for tproxy method?

@brianmay
Copy link
Member

What you have got looks OK. But don't be put off making changes the interfaces either. It isn't like I put a lot of thought into these interfaces or anything.

Another possibility is that the test calls method.set_firewall() with a dummy firewall object.

@brianmay brianmay merged commit 7c33886 into sshuttle:master Dec 27, 2020
'-m', 'udp', '-p', 'udp', '--dport', '53')
_ipt('-A', tproxy_chain, '-j', 'TPROXY',
'--tproxy-mark', '0x1/0x1',
'--tproxy-mark', '0x'+tmark+'/0x'+tmark,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there's a bug here: eg if tmark was '10', then --set-mark would set the mark to 10 for locally generated packets, but tproxy-mark would set the mark to 0x10 (i.e. 16) for packets arriving from the local network.

Also: the part after the slash is the mask, and doesn't have to be equal to the mark. tmark should probably default to 1/1, and be used directly without any 0x prefix. That way the flag can specify the value and mask.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for that comment @normanr , you're right. That should be improved here just as you mention. Maybe better to create a new PR since this is already closed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants