# Native IPv6, how to ignore global dynamic IP from router?

## Biker

Background

I have what is marketed as "Native IPv6" from my ISP (free.fr) in France.

I have been given an IPv6 prefix like: '2a01:e35:xxxx:xxxx::/64'

My ISP unconditionally provides me a router that I must use between my LAN and their ATM line to reach the public Internet.

I run a local DNS server on my LAN for maintaining address resolution within the same LAN. (Very useful for ssh, scp, apache, MySQL, etc.)

My progress

I have successfully setup a few computers (running Gentoo Linux) in my LAN with IPv6 addresses that I have chosen myself, but of course selected from within my IPv6 prefix '2a01:e35:xxxx:xxxx::/64'.

For instance, I have given one of my computers the address '2a01:e35:xxxx:xxxx::3:/64' in the '/etc/conf.d/net' configuration file. (Because, it's IPv4 address is 'xxx.xxx.xxx.3' and for me it makes things simple and easy to remember.)

My problem

The LAN computer that I've configured with the 'static' IPv6 address will ALSO pickup a router advertised dynamic address like: '2a01:e35:xxxx:xxxx:xxxx:70ff:fe6b:xxxx/64 scope global dynamic'. When I 'ssh -6' to another IPv6 computer within my LAN the target computer sees the request coming from the dynamic address '2a01:e35:xxxx:xxxx:xxxx:70ff:fe6b:xxxx/64 scope global dynamic'. Not from the 'static' address that I have set to '2a01:e35:xxxx:xxxx::3:/64 scope global'.

When I try to limit access to the second computer (also IPv6) within my LAN, so that my first computer shall be able to reach it, I'd like to 'ACCEPT 2a01:e35:xxxx:xxxx::3:/64' but I don't want to ACCEPT the whole '2a01:e35:xxxx:xxxx::/64'.

I do have one computer (my cellular phone) which I want to pickup the router advertised global dynamic address. But only this one. So, I don't want the ISP router to stop advertise dynamic addresses. And anyway, I have no means to STOP the router from distributing the dynamic addresses.

My needs

What I DO want to do is to configure my '2a01:e35:xxxx:xxxx::3:/64 scope global' computer to NOT request or accept any router advertised dynamic address.

(I hated DHCP, never used it. I don't want my computers to run on dynamic IPv6 addresses either.)

But, how?

I've looked through all IPv6 related configuration in the kernel. I've studied all that I can find about configuring '/etc/conf.d/net' but I haven't found anything.

Would be extremely happy if someone could point me in the right direction.

Best regards

Biker

----------

## py-ro

Hint:

```
/proc/sys/net/ipv6/conf/$NITERFACE/accept_ra
```

bye

py

----------

## Biker

 *py-ro wrote:*   

> Hint:
> 
> ```
> /proc/sys/net/ipv6/conf/$NITERFACE/accept_ra
> ```
> ...

 

Got it. Thanks a million. Will report back after implementation.

Biker

----------

## Biker

OK, I'm up and running the way I wanted to. Thanks again.

First thing I did was

```
echo -n '0' >/proc/sys/net/ipv6/conf/eth0/accept_ra

/etc/init.d/net.eth0 restart

ip -6 addr show

```

I could now see that there was no more any '2a01:e35:xxxx:xxxx:xxxx:70ff:fe6b:xxxx/64 scope global dynamic' address.

My '2a01:e35:xxxx:xxxx::3:/64 scope global' was still there, and UP. So, the POC was successful.

Test

I could successfully 'ping6' any of my IPv6 configured computers in my LAN. Especially, I could 'ping6' their static 'scope global' addresses, that I have configured myself (from my own prefix, of course).

Problem

```
ping6 ipv6.google.com -c 3
```

failed with "network unreachable".

So, I realized that I now had no good 'default gw' and that I needed to point my LAN computers to the IPS provided router to get out on the public Internet. Fine, but what's the IPv6 address of the router? This address is not explicitly documented by my ISP. Partially, since they have designed their 'product' for 'autoconf'. (Which I'm trying to avoid here.) And partially because they... (Well, let's not go down that route.  :Wink:  And of course, in their mind, people use nothing but Windows, so any type of automatic configuration must be the preferred way for the majority of their clients. Well, not for me, it ain't.

Router IPv6 address

I set back my computer to 'autoconf' mode.

```
echo -n '1' >/proc/sys/net/ipv6/conf/eth0/accept_ra

/etc/init.d/net.eth0 restart

```

Then I did a 'traceroute6' to ipv6.google.com and I could see that the first hop went to '2a01:e35:xxxx:xxxx::', i.e. to 'address zero' within my IPv6 prefix. This made absolute sense to me. (I believe having read somewhere that the 'address zero' could/should be used for such purposes, but I can't for my life find it back.)

Anyway, I now set "default via 2a01:e35:xxxx:xxxx::" in my /etc/conf.d/net configuration file.

```

routes_eth0="default via xxx.xxx.xxx.254

             default via 2a01:0e35:xxxx:xxxx::"

```

Test with default gateway

```

echo -n '0' >/proc/sys/net/ipv6/conf/eth0/accept_ra

/etc/init.d/net.eth0 restart

ping6 ipv6.google.com -c 3

```

Success!! Now it works as I want it to.

Persistence

I needed a way to automate this configuration and to make sure it would persist a reboot. My approach became to code this in the '/etc/conf.d/net' configuration file.

There is this nice feature of a 

```
preup()
```

 function that we can implement ourselves to be creative. This is where I would echo the '0' to the '/proc/sys/net/ipv6/conf/eth0/accept_ra' file. (Read '/usr/share/doc/openrc-*/net.example.bz2' for details about the 'preup()' feature.) Careful! The '/etc/conf.d/net' configuration file is called for all network interfaces, including 'lo' and any potential 'eth1', eth2', etc.

Furthermore, I wanted to develop this in one of my computers and distribute the solution to all of my IPv6 Gentoo computers within the LAN. Especially, I don't like to do maintenance in several places. And I already use 'unison' in my LAN...

So, I wrote a small(?) bash script that I store under /usr/local/ipv6, that I can thereby very simply distribute with unison. Especially, should I amend (likely) or improve (potentially) my script, the changes will propagate through the LAN within a 'short while'. This bash script will then be sourced into the '/etc/conf.d/net' file. Careful! Not "called from" or "executed from", but "sourced into". (This is my choice and it's what makes my implementation smooth. As always, your mileage may vary. As do your preferences.)

I had to enter the following code snipped into each computers '/etc/conf.d/net' file.

```
preup() {

    if [[ ${IFACE} == 'eth0' ]]; then

        if [[ -f /usr/local/ipv6/inhibit_dynamic_ipv6_address ]]; then

            source /usr/local/ipv6/inhibit_dynamic_ipv6_address

        fi

    fi

    return 0

}
```

If you already have a 'preup()' function in your 'net', then you'll also know how to integrate this logic into the existing 'preup()'.

The unconditional return of true (0) makes sure that if my routine for refusing dynamic IPv6 addresses should fail, then the interface will still (hopefully) come up. Returning false (1) on failure will stop the interface from coming up. To each and everyone his pleasure. Again, a question of preferences and needs.

External script

Since my external script is sourced, it has direct access to the ${IFACE} variable. It can also directly call 'ebegin()' and 'eerror()' for user feedback.

On a general point of view, the payload logic of my script does

```
echo -n '0' >"/proc/sys/net/ipv6/conf/${IFACE}/accept_ra"
```

but then, the way that I am, I've added a lot of error handling and feedback logic to the script. (And adding to it still.) That's my hubris. If you want to go for the 'simplest' solution, it would probably be to add

```
preup() {

    if [[ ${IFACE} == 'eth0' ]]; then

        echo -n '0' >"/proc/sys/net/ipv6/conf/${IFACE}/accept_ra"

    fi

    return 0

}
```

to your '/etc/conf.d/net' file.

My old bosses would have liked that. They never looked for solutions that could evolve and be improved upon. They only want it "to work now" and not to spend one minute more than absolutely necessary on the solution.

Conclusion

This is a solution that 'works for me'. Yours may be different.

Again, thanks to 'py-ro' for his (her?) pointer in this direction.

There are several places where you may find information about the files in the '/proc/sys/net/ipv6/conf/${IFACE}/' directory. Google and others may help. One source that I've found is: http://www.tldp.org/HOWTO/Linux+IPv6-HOWTO/chapter-kernel-settings.html, but there will be many mirrors of this information.

If you read it this far, you're probably alone.  :Wink:  Anyway, you may have found some hints for how to improve your own situation. At least, I hope so.

Cheers

Biker

----------

## py-ro

```
echo -n '0' >"/proc/sys/net/ipv6/conf/${IFACE}/accept_ra"
```

You should use sysctl for these.

----------

## Biker

 *py-ro wrote:*   

> You should use sysctl for these.

 

Looking in to it. (By chance, I can improve the script in one place and it will propagate through my network.)   :Wink: 

Biker

----------

## couker

The "cleanest" solution is to disable A flag in router advertisement for the prefix on your router and have RA enabled on your client side. If you disable the A flag, the client accept only default route and is not allowed to generate its own IPv6 address. However, you must have control over your router and the firmware must support it which can be a problem.

----------

## Biker

 *couker wrote:*   

> However, you must have control over your router ... which can be a problem.

 

It's my problem. My French ISP (free.fr) provides me with a mandatory router which will not let me do any advanced configuration.

But, apart from that, of course I agree with you.

Biker

----------

## truc

But you know those automatically generated addresses(I'm talking about the privacy extension, use_tempaddr) are not there to hurt you, right? It's the other way around, just look for "super cookie" and IPv6 on your favorite search engine.

----------

## py-ro

We weren't talking about privacy extension, this are another Topic. This was about stateless autoconfiguration issues, on top of that you can use privacy extension.

----------

