4

Switched providers the other day, they only assign DSlite-connections. I'm fine, I thought. Thing is - I want to access some of my stuff from outside of my network, which should be of much less a hassle now I got native IPv6.

My new main problem was that I can't assume to have that everywhere I roam, so most of the time I'll try to access from an IPv4-only entry point. Found $ socat was my friend, as I can access one box with true dualstack connection - so accessing my IPv6 from an IPv4-only connection is as easy as running $ socat UDP4-LISTEN:sourceport,fork,su=nobody UDP6:my-ipv6-hostname-behind.cgn:targetport on the dualstacked machine and afterwards connecting to my-dualstack-hostna.me:sourceport from outside.

Now, $ netstat -tulpen | grep sourceport on the dualstacked machine only reveals an UDP4-listener - so my current problem is:

  • Access from IPv6-only connection requires me to connect to my-ipv6-hostname-behind.cgn:targetport
  • Access from IPv4-only connection requires me to connect to my-dualstack-hostna.me:sourceport
  • Access from DS(-lite) connection enables me to use both, but preferably use the direct IPv6-route

So it would be great to be able to use my-dualstack-hostna.me:sourceport for both IPv4 and IPv6 connections and not to root-update the configuration every time I move my laptop or phone! How to make socat listen on both? There has to be a way! $ netstat -tulpen | grep ":22" on the DS-machine shows these:

tcp        0      0 0.0.0.0:22 […]
tcp6       0      0 :::22      […]
2
  • Your netstat output is showing something listening to both TCPv4, and TCPv6. So it isn't clear to me what isn't working?
    – Zoredache
    Feb 18, 2015 at 18:44
  • 22 is not my sourceport. Last output is only proof for that it's feasible to make something listen on both IPv6 and IPv6. It just shows an SSH server, not the forwarding created by socat. As stated before, "$ netstat -tulpen | grep sourceport on the dualstacked machine only reveals an UDP4-listener", like udp 0 0 0.0.0.0:sourceport […]
    – LDericher
    Feb 18, 2015 at 18:54

2 Answers 2

4

I had the same issue - you can solve it by running two instances of socat, one listening on ipv4 and one listening on the same ipv6 port by binding each to its respective address, like this:

socat UDP4-LISTEN:sourceport,bind=<ipv4-addr>,fork,su=nobody UDP6:my-ipv6-hostname-behind.cgn:targetport

socat UDP6-LISTEN:sourceport,bind=<ipv6-addr>,fork,su=nobody UDP6:my-ipv6-hostname-behind.cgn:targetport
4

You can configure socat to listen on both IPv4 and IPv6 by, counter-intuitively, always use the "TCP6-LISTENER" or "UDP6-LISTENER" address forms. This causes socat to listen in a dual-stack manner. This is because by default Linux (and I suspect the BSDs) also accept IPv4 when the socket has been bound for ::.

$ socat -v tcp6-listen:8000,fork,max-children=500,reuseaddr exec:"$(which cat)"

We can see socat now support dual stack.

$ ss -ntpl | rg socat
LISTEN 0      5                  *:8000             *:*    users:(("socat",pid=1568208,fd=5))

$ echo "test" | nc 127.0.0.1 8000
test
^C

$ echo "test" | nc ::1 8000
test
^C

If you're using socat in an environment where you actually want just IPv6, you can pass the ipv6only option. This sets the IPV6_V6ONLY socket option, which is described in ipv6(7):

IPV6_V6ONLY (since Linux 2.4.21 and 2.6)  
        If this flag is set to true (nonzero), then the  socket  is  re‐  
        stricted  to  sending  and receiving IPv6 packets only.  In this  
        case, an IPv4 and an IPv6 application can bind to a single  port  
        at the same time.

        If this flag is set to false (zero), then the socket can be used
        to send and receive packets to and from an IPv6  address  or  an
        IPv4-mapped IPv6 address.

$ socat -v tcp6-listen:8000,fork,max-children=500,reuseaddr,ipv6only exec:"$(which cat)

We can then observable this change:

$ ss -ntpl | rg socat
LISTEN 0      5               [::]:8000          [::]:*    users:(("socat",pid=1573995,fd=5))

$ echo "test" | nc 127.0.0.1 8000

$ echo "test" | nc ::1 8000
test
^C
1
  • 1
    This should be the accepted answer.
    – ReeseWang
    Aug 12, 2023 at 13:49

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .