Du kannst nicht mehr als 25 Themen auswählen Themen müssen mit entweder einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. #!/bin/bash
  2. if [ -z "$1" ] || [ -z "$2" ] || [ -z "$3" ] || [ -z "$4" ]; then
  3. echo 'usage: ./natfwd.sh <action> <extif> <port> <netns>'
  4. exit 1
  5. fi
  6. if [ "$UID" -ne 0 ] && [ -z "$SKIP_ROOT_CHECK" ]; then
  7. echo 'must be root!'
  8. exit 1
  9. fi
  10. # Check if we should add an exemption for UFW.
  11. ufw=no
  12. if [ "$1" = "--ufw" ]; then
  13. ufw=yes
  14. shift
  15. fi
  16. action=$1
  17. extip=$2
  18. ports=$3
  19. netnsname=$4
  20. pipeouter=$netnsname"_veth0"
  21. pipeinner=$netnsname"_veth1"
  22. # use /31 here to minimize chance of something fucking up later
  23. # CONFIG: change pouterip and pinnerip to something in case there's a conflict,
  24. # but there probably won't be
  25. pouterip=192.168.69.42
  26. pinnerip=192.168.69.43
  27. pouteripmasked=$pouterip/31
  28. pinneripmasked=$pinnerip/31
  29. # Used in testing:
  30. # -A PREROUTING -d 192.168.1.9/32 -p tcp -m tcp --dport 1337 -j DNAT --to-destination 10.13.37.69
  31. # -A POSTROUTING -d 10.13.37.69/32 -p tcp -m tcp --dport 1337 -j SNAT --to-source 10.13.37.42
  32. dnatrule="PREROUTING -d $extip -p tcp --dport $port -j DNAT --to-destination $pinnerip"
  33. snatrule="POSTROUTING -d $pinnerip -p tcp --dport $port -j SNAT --to-source $pouterip"
  34. function get_dnat_rule {
  35. port=$1
  36. echo "PREROUTING -d $extip -p tcp --dport $port -j DNAT --to-destination $pinnerip"
  37. }
  38. function get_snat_rule {
  39. port=$1
  40. echo "POSTROUTING -d $pinnerip -p tcp --dport $port -j SNAT --to-source $pouterip"
  41. }
  42. function get_ufw_rule {
  43. port=$1
  44. echo "proto tcp from any to $pinnerip port $port"
  45. }
  46. # CONFIG: make sure this is set right
  47. ufwcomment="natfwd_"$netnsname
  48. if [ $action = "enable" ]; then
  49. echo 'enabling'
  50. set -x
  51. # Make sure we have IP forwarding enabled. We don't bother disabling
  52. # this later.
  53. sysctl -w net.ipv4.ip_forward=1 > /dev/null
  54. # Create the interface and move to the network namespace.
  55. ip link add $pipeouter type veth peer name $pipeinner
  56. ip link set $pipeinner netns $netnsname
  57. # Assign IP addresses to the new devices.
  58. ip addr add $pouteripmasked dev $pipeouter
  59. ip netns exec $netnsname ip addr add $pinneripmasked dev $pipeinner
  60. # Create the routing rules to allow the packets.
  61. for p in $ports; do
  62. iptables -t nat -A $(get_dnat_rule $p)
  63. iptables -t nat -A $(get_snat_rule $p)
  64. done
  65. [ "$ufw" = "yes" ] && [ -z "$(ufw status | grep '# $ufwcomment')" ] && \
  66. for p in $ports; do
  67. ufw route allow $(get_ufw_rule $p) comment $ufwcomment
  68. done
  69. # Enable the interfaces.
  70. ip link set dev $pipeouter up
  71. ip netns exec $netnsname ip link set dev $pipeinner up
  72. elif [ $action = "disable" ]; then
  73. echo 'disabling'
  74. set -x
  75. # Delete the routing rules. Deleting the interfaces doesn't
  76. # automatically remove these.
  77. for p in $ports; do
  78. iptables -t nat -D $(get_dnat_rule $p)
  79. iptables -t nat -D $(get_snat_rule $p)
  80. done
  81. if [ "$ufw" = "yes" ]; then
  82. rulenum=$(ufw status numbered | grep "# $ufwcomment" | awk '{ print substr($1, 2, length($1) - 2) }')
  83. if [ -n "$rulenum" ]; then
  84. yes | ufw delete $rulenum
  85. fi
  86. fi
  87. # Deleting this interface deletes everything else associated with it.
  88. ip link delete $pipeouter
  89. else
  90. echo 'actions are "enable" or "disable"'
  91. exit 1
  92. fi
  93. set +x
  94. echo 'OK'