With the command like these the following you can add neighbor proxies in Linux
ip -6 neigh add proxy 2001:db8:100:3022:1::4 dev eth0
Is there a way how to list which proxies have already been defined?
ipv6linux
With the command like these the following you can add neighbor proxies in Linux
ip -6 neigh add proxy 2001:db8:100:3022:1::4 dev eth0
Is there a way how to list which proxies have already been defined?
First and foremost, there is nothing to fear from being on a public IP allocation, so long as your security devices are configured right.
What should I be replacing NAT with, if we don't have physically separate networks?
The same thing we've been physically separating them with since the 1980's, routers and firewalls. The one big security gain you get with NAT is that it forces you into a default-deny configuration. In order to get any service through it, you have to explicitly punch holes. The fancier devices even allow you to apply IP-based ACLs to those holes, just like a firewall. Probably because they have 'Firewall' on the box, actually.
A correctly configured firewall provides exactly the same service as a NAT gateway. NAT gateways are frequently used because they're easier to get into a secure config than most firewalls.
I hear that IPv6 and IPSEC are supposed to make all this secure somehow, but without physically separated networks that make these devices invisible to the Internet, I really can't see how.
This is a misconception. I work for a University that has a /16 IPv4 allocation, and the vast, vast majority of our IP address consumption is on that public allocation. Certainly all of our end-user workstations and printers. Our RFC1918 consumption is limited to network devices and certain specific servers where such addresses are required. I would not be surprised if you just shivered just now, because I certainly did when I showed up on my first day and saw the post-it on my monitor with my IP address.
And yet, we survive. Why? Because we have an exterior firewall configured for default-deny with limited ICMP throughput. Just because 140.160.123.45 is theoretically routeable, does not mean you can get there from wherever you are on the public internet. This is what firewalls were designed to do.
Given the right router configs, and different subnets in our allocation can be completely unreachable from each other. You do can do this in router tables or firewalls. This is a separate network and has satisfied our security auditors in the past.
There's no way in hell I'll put our billing database (With lots of credit card information!) on the internet for everyone to see.
Our billing database is on a public IPv4 address, and has been for its entire existence, but we have proof you can't get there from here. Just because an address is on the public v4 routeable list does not mean it is guaranteed to be delivered. The two firewalls between the evils of the Internet and the actual database ports filter out the evil. Even from my desk, behind the first firewall, I can't get to that database.
Credit-card information is one special case. That's subject to the PCI-DSS standards, and the standards state directly that servers that contain such data have to be behind a NAT gateway1. Ours are, and these three servers represent our total server usage of RFC1918 addresses. It doesn't add any security, just a layer of complexity, but we need to get that checkbox checked for audits.
The original "IPv6 makes NAT a thing of the past" idea was put forward before the Internet boom really hit full mainstream. In 1995 NAT was a workaround for getting around a small IP allocation. In 2005 it was enshrined in many Security Best Practices document, and at least one major standard (PCI-DSS to be specific). The only concrete benefit NAT gives is that an external entity performing recon on the network doesn't know what the IP landscape looks like behind the NAT device (though thanks to RFC1918 they have a good guess), and on NAT-free IPv4 (such as my work) that isn't the case. It's a small step in defense-in-depth, not a big one.
The replacement for RFC1918 addresses are what are called Unique Local Addresses. Like RFC1918, they don't route unless peers specifically agree to let them route. Unlike RFC1918, they are (probably) globally unique. IPv6 address translators that translate a ULA to a Global IP do exist in the higher range perimeter gear, definitely not in the SOHO gear yet.
You can survive just fine with a public IP address. Just keep in mind that 'public' does not guarantee 'reachable', and you'll be fine.
2017 update
In the past few months, Amazon aws has been adding IPv6 support. It has just been added to their amazon-vpc offering, and their implementation gives some clues as to how large scale deployments are expected to be done.
To add one of the security benefits of NAT back in, they are now offering an Egress-only Internet Gateway. This offers one NAT-like benefit:
Which provides a layer of defense-in-depth, in case a misconfigred firewall rule accidentally allows inbound traffic.
This offering does not translate the internal address into a single address the way NAT does. Outbound traffic will still have the source IP of the instance that opened the connection. Firewall operators looking to whitelist resources in the VPC will be better off whitelisting netblocks, rather than specific IP addresses.
Routeable does not always mean reachable.
1: The PCI-DSS standards changed in October 2010, the statement mandating RFC1918 addresses was removed, and 'network isolation' replaced it.
Timothy Baldwins answer put me on the right track, although the answer was rather cryptic. IPv6 neighbor advertisements/solicitation is like ARP for IPv6. It's used to "see" other machines on the network. The router send a neighbor solicitation on which the machine (server or client) should reply on with a neighbor advertisement.
Even with net.ipv6.conf.all.forwarding
set to 1
, neighbor advertisements and solicitations are not forwarded. To make eth0 forward neighbor advertisements and solicitations, eth0 should be set as proxy for the IPv6 address of the client behind tap0, and proxying for neighbor stuff should be enabled for eth0:
echo 1 > /proc/sys/net/ipv6/conf/eth0/proxy_ndp
/sbin/ip -6 neigh add proxy 2001:db8::100:abc:2 dev eth0
Unfortunately, it's not possible to retrieve the list of proxies added, nor does ip -6
show error messages on repeatedly executing the command. Neither am I sure if "neigh del proxy" works, it does not give an error message and the C source is not really meaningful to me.
As I do not want to do everything manually, I've created a script which does the work for me.
IPv6 addresses are based on the IPv4 part (the 1 in 10.8.0.1). The prefix and netmask are stored in /etc/openvpn/variables
.
The next steps are made for setting up OpenVPN with encrypted IPv4/IPv6 connectivity to the Internet over a native IPv4 connection. RSA keys and tls-auth are used for authentication and MITM prevention.
/etc/openvpn/variables
contains variables which are used for the up script (run on startup, after creation of tap0 device) and client-connect script (run after the client has authenticated).
# this prefix is handled out by the provider, replace it with your own prefix
prefix=2001:db8::abc
# netmask, 2001:db9::abc:0000 - 2001:db9::abc:FFFF
prefixlen=112
/etc/openvpn/server-clientconnect.sh
is executed as root and makes sure that IPv6 is routed properly by adding the IPv6 address to the eth0 proxy. Because client-connect
is called after OpenVPN switched to the user specified by the User
setting, sudo
is needed to give the script sufficient permissions to run as root. Of course, variables should be checked before using, the number should be between and including 2 ad 254. (1 is the gateway, 255 the broadcast address).
#!/bin/sh
. /etc/openvpn/variables
if [ -z "$ifconfig_pool_remote_ip" ]; then
echo "Missing environment variable."
exit 1
fi
ipp=$(echo "$ifconfig_pool_remote_ip" | cut -d. -f4)
if ! [ "$ipp" -ge 2 -a "$ipp" -le 254 ] 2>/dev/null; then
echo "Invalid IP part."
exit 1
fi
hexipp=$(printf '%x' $ipp)
/sbin/ip -6 neigh add proxy $pfx:$hexipp dev eth0
To make this work, the user vpn
should be allowed to run the script while preserving $ifconfig_pool_remote_ip
which contains the remote network IPv4 address. Add the next lines to the sudoers file by executing sudo visudo
and appending:
Defaults:vpn env_keep=ifconfig_pool_remote_ip
vpn ALL=NOPASSWD: /etc/openvpn/server-clientconnect.sh
/etc/openvpn/server-up.sh
enables IPv4, IPv6 forwarding (eth0+tap0 did not work, it really had to be all
) and neighbor proxy on eth0. It adds the gateway address to servers tap0
too.
#!/bin/sh
. /etc/openvpn/variables
/sbin/ip -6 addr add $pfx:1/$pfxlen dev $dev
echo 1 > /proc/sys/net/ipv4/ip_forward
echo 1 > /proc/sys/net/ipv6/conf/all/forwarding
echo 1 > /proc/sys/net/ipv6/conf/eth0/proxy_ndp
Finally, the OpenVPN configuration file at /etc/openvpn/internet.conf
:
proto udp
dev tap
ca ca.crt
cert server.crt
key server.key
dh dh1024.pem
server 10.8.0.0 255.255.255.0
script-security 2
up /etc/openvpn/server-up.sh
client-connect "/usr/bin/sudo -u root /etc/openvpn/server-clientconnect.sh"
# encrypt all traffic
push "redirect-gateway def1"
# keep the same IP addresses each time
ifconfig-pool-persist ipp.txt
keepalive 10 120
tls-auth ta.key 0
cipher BF-CBC
comp-lzo
# OpenVPN will switch to this user, it is also used for sudo
user vpn
group vpn
persist-key
persist-tun
For completeness, permissions and ownerships of files in /etc/openvpn
:
drwx------ root root .
-rw------- root root ca.crt
-rw------- root root dh1024.pem
drwx------ root root easy-rsa <-- left from creation of keys
-rw------- root root ipp.txt
-rwx------ root root server-clientconnect.sh
-rw------- root root internet.conf
-rw------- root root variables
-rwx------ root root server-up.sh
-rw------- root root server.crt
-rw------- root root server.key
-rw------- root root ta.key
-rwx------ root root update-resolv-conf <-- this was installed by default
Firewall settings:
itpables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -s 10.8.0.0/24 -i tap0 -o eth0 -j ACCEPT
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE
ip6tables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
ip6tables -A FORWARD -s 2001::db8::abc:0/112 -i tap0 -o eth0 -j ACCEPT
/etc/openvpn/client.conf
:
client
dev tap
proto udp
remote 178.21.112.251 1194
script-security 2
up /etc/openvpn/client-up.sh
resolv-retry infinite
nobind
user nobody
group nogroup
persist-key
persist-tun
ca ca.crt
cert home.crt
key home.key
ns-cert-type server
tls-auth ta.key 1
cipher BF-CBC
comp-lzo
ta.key
and ca.key
are the same files from the server. home.key
and home.crt
are files, created on the server.
client-up.sh
adds the IPv6 address and route (based on IPv4 address):
#!/bin/sh
pfx='2001:db8::abc'
pfxlen=112
hexippart=`printf '%x' "$(echo $ifconfig_local | cut -d. -f4)"`
/sbin/ip -6 addr add $pfx:$hexippart/$pfxlen dev $dev
/sbin/ip -6 route add default via $pfx:1 dev $dev
The guide at http://www.ipsidixit.net/2010/03/24/239/ was very helpful and OpenVPN manual page is useful for information about various settings.
Best Answer
Try with:
It works for me: