diff --git a/README.md b/README.md index 268a57a..6be94d3 100644 --- a/README.md +++ b/README.md @@ -4,3 +4,4 @@ This BOSH release includes some jobs that are unmerged pull requests to other re * `prepare_env` is https://github.com/cloudfoundry/os-conf-release/pull/19 * `cf-admin-user` is https://github.com/cloudfoundry/capi-release/pull/65 +* `port_forwarding` is https://github.com/cloudfoundry/networking-release/pull/13 diff --git a/jobs/port_forwarding/monit b/jobs/port_forwarding/monit new file mode 100644 index 0000000..3cb88fc --- /dev/null +++ b/jobs/port_forwarding/monit @@ -0,0 +1,5 @@ +check file port_forwarding + with path /var/vcap/sys/run/port_forwarding/port_forwarding.check + start program "/var/vcap/jobs/port_forwarding/bin/ctl start" + stop program "/var/vcap/jobs/port_forwarding/bin/ctl stop" + group vcap diff --git a/jobs/port_forwarding/spec b/jobs/port_forwarding/spec new file mode 100644 index 0000000..4775758 --- /dev/null +++ b/jobs/port_forwarding/spec @@ -0,0 +1,21 @@ +--- +name: port_forwarding + +packages: [] + +templates: + bin/ctl: bin/ctl + bin/forward_ports.sh.erb: bin/forward_ports.sh + bin/unforward_ports.sh.erb: bin/unforward_ports.sh + +properties: + networking.port_forwarding: + description: "List of rules that describes the ports to be forwarded. Defaults `internal_ip` to '127.0.0.1'." + default: [] + example: + - external_port: 80 + internal_ip: 10.10.0.34 + internal_port: 8080 + - external_port: 443 + internal_ip: 10.10.0.34 + internal_port: 4443 diff --git a/jobs/port_forwarding/templates/bin/ctl b/jobs/port_forwarding/templates/bin/ctl new file mode 100644 index 0000000..119ca3a --- /dev/null +++ b/jobs/port_forwarding/templates/bin/ctl @@ -0,0 +1,29 @@ +#!/bin/bash + +set -e -u + +LOG_DIR=/var/vcap/sys/log/port_forwarding +RUN_DIR=/var/vcap/sys/run/port_forwarding + +mkdir -p $RUN_DIR $LOG_DIR + +exec >>$LOG_DIR/stdout.log 2>&1 + +case $1 in + + start) + echo -n "Applying iptables rules for port forwarding" + /var/vcap/jobs/port_forwarding/bin/forward_ports.sh + touch $RUN_DIR/port_forwarding.check + ;; + + stop) + echo -n "Removing iptables rules for port forwarding" + /var/vcap/jobs/port_forwarding/bin/unforward_ports.sh + rm -f $RUN_DIR/port_forwarding.check + ;; + *) + +esac + +exit 0 diff --git a/jobs/port_forwarding/templates/bin/forward_ports.sh.erb b/jobs/port_forwarding/templates/bin/forward_ports.sh.erb new file mode 100644 index 0000000..7d4a6c5 --- /dev/null +++ b/jobs/port_forwarding/templates/bin/forward_ports.sh.erb @@ -0,0 +1,40 @@ +#!/bin/bash + +CHAIN="portforwarding-release" + +function forward_exists { + set -e + chain=$1 + iptables -t nat -C ${chain} -j ${CHAIN} 2>/dev/null +} + +if ! iptables -t nat -L ${CHAIN} >/dev/null 2>&1; then + iptables -t nat -N ${CHAIN} +fi + +if ! forward_exists PREROUTING; then + iptables -t nat -A PREROUTING -j ${CHAIN} +fi + +if ! forward_exists OUTPUT; then + iptables -t nat -A OUTPUT -j ${CHAIN} +fi + +iptables -F ${CHAIN} || true + +sysctl net.ipv4.conf.all.route_localnet=1 + +<% p("networking.port_forwarding").each do |rule| %> + <% + external_ip = rule['external_ip'] || spec.address + external_port = rule['external_port'] || raise("Expected non-empty 'external_port' on '#{rule.inspect}' rule") + internal_ip = rule['internal_ip'] || "127.0.0.1" + internal_port = rule['internal_port'] || raise("Expected non-empty 'internal_port' on '#{rule.inspect}' rule") + -%> + # external clients + sudo iptables -t nat -A portforwarding-release -p tcp -d <%= external_ip %> --dport <%= external_port %> -j DNAT --to <%= internal_ip %>:<%= internal_port %> + + # loopback + sudo iptables -t nat -A portforwarding-release -p tcp -d 127.0.0.1 --dport <%= external_port %> -j DNAT --to <%= internal_ip %>:<%= internal_port %> -o lo + +<% end %> diff --git a/jobs/port_forwarding/templates/bin/unforward_ports.sh.erb b/jobs/port_forwarding/templates/bin/unforward_ports.sh.erb new file mode 100644 index 0000000..fa6f562 --- /dev/null +++ b/jobs/port_forwarding/templates/bin/unforward_ports.sh.erb @@ -0,0 +1,3 @@ +#!/bin/bash + +iptables -t nat -F portforwarding-release