2009-03-02 12:27:43

by martin f krafft

[permalink] [raw]
Subject: /proc/sys/net/ip*/conf/all/* does not actually affect interfaces

Dear kernel gurus,

I was unpleasantly surprised last night that a rogue machine managed
to alter the IPv6 default route of one of my servers, despite my
sysctl configuration, which disables RA for "all" interfaces during
the boot sequence. It also changes the "default" values:

net.ipv6.conf.default.autoconf = 0
net.ipv6.conf.default.accept_ra = 0
net.ipv6.conf.default.accept_ra_defrtr = 0
net.ipv6.conf.default.accept_ra_pinfo = 0
net.ipv6.conf.default.accept_source_route = 0
net.ipv6.conf.default.accept_redirects = 0
net.ipv6.conf.default.forwarding = 0
net.ipv6.conf.all.autoconf = 0
net.ipv6.conf.all.accept_ra = 0
net.ipv6.conf.all.accept_ra_defrtr = 0
net.ipv6.conf.all.accept_ra_pinfo = 0
net.ipv6.conf.all.accept_source_route = 0
net.ipv6.conf.all.accept_redirects = 0
net.ipv6.conf.all.forwarding = 0

Yet, net.ipv6.conf.eth0.* values were unchanged, and routing
advertisements honoured.

This also applies to files in ipv4/, e.g. accept_redirects

A bit of investigation shows that something fishy is going on, or
at least it's unexpected to me, because I recall the conf/all/*
interface to do what it promised to do a while ago. Not anymore
though.

seamus# pwd
/proc/sys/net
seamus# head ipv4/conf/{all,eth0}/accept_redirects
==> ipv4/conf/all/accept_redirects <==
1

==> ipv4/conf/eth0/accept_redirects <==
1
seamus# echo 0 >| ipv4/conf/all/accept_redirects
seamus# head ipv4/conf/{all,eth0}/accept_redirects
==> ipv4/conf/all/accept_redirects <==
0

==> ipv4/conf/eth0/accept_redirects <==
1



***** shouldn't ipv4/conf/eth0/accept_redirects be 0 too??


same with ipv6:

seamus# head ipv6/conf/{all,eth0}/accept_ra
==> ipv6/conf/all/accept_ra <==
1

==> ipv6/conf/eth0/accept_ra <==
1
seamus# echo 0 >| ipv6/conf/all/accept_ra
seamus# head ipv6/conf/{all,eth0}/accept_ra
==> ipv6/conf/all/accept_ra <==
0

==> ipv6/conf/eth0/accept_ra <==
1



What is going on? Is this my fault, did something change in the
kernel, or is this a bug?

--
martin | http://madduck.net/ | http://two.sentenc.es/

"in the figure of the president, george w. bush, the incompetence,
stupidity, and sheer inhumanity that characterize so much of
america's money-mad corporate elite find their quintessentially
repulsive expression."
-- journalist, aftermath of katrina

spamtraps: [email protected]


Attachments:
(No filename) (2.32 kB)
digital_signature_gpg.asc (197.00 B)
Digital signature (see http://martin-krafft.net/gpg/)
Download all attachments

2009-03-02 18:55:40

by martin f krafft

[permalink] [raw]
Subject: Re: /proc/sys/net/ip*/conf/all/* does not actually affect interfaces

also sprach martin f krafft <[email protected]> [2009.03.02.1327 +0100]:
> A bit of investigation shows that something fishy is going on, or
> at least it's unexpected to me, because I recall the conf/all/*
> interface to do what it promised to do a while ago. Not anymore
> though.

Sorry for being an idiot and not including the important data: this
happens on Debian kernels 2.6.24-.28 across several machines.
I checked the Debian diff but could not find anything that seems
related, and I reproduced it with 2.6.29-rc6-git5.

Thanks,

--
martin | http://madduck.net/ | http://two.sentenc.es/

the security, stability and reliability of a computer system
is reciprocally proportional to
the amount of vacuity between the ears of the admin.

spamtraps: [email protected]


Attachments:
(No filename) (787.00 B)
digital_signature_gpg.asc (197.00 B)
Digital signature (see http://martin-krafft.net/gpg/)
Download all attachments

2009-03-03 07:00:37

by Philipp Matthias Hahn

[permalink] [raw]
Subject: Re: /proc/sys/net/ip*/conf/all/* does not actually affect interfaces

Hello!

On Mon, Mar 02, 2009 at 01:27:18PM +0100, martin f krafft wrote:
> I was unpleasantly surprised last night that a rogue machine managed
> to alter the IPv6 default route of one of my servers, despite my
> sysctl configuration, which disables RA for "all" interfaces during
> the boot sequence. It also changes the "default" values:
...
> Yet, net.ipv6.conf.eth0.* values were unchanged, and routing
> advertisements honoured.
>
> This also applies to files in ipv4/, e.g. accept_redirects
...

As far as I researched for IPv4 some time ago, the "default" value gets
copied to newly created interfaces only once.
"all" on the other hand allways gets applied in addition to the current
setting, but it depends on the exact setting, if its ORed, ANDed, or
whatevered:
log_martians OR
accept_redirects AND
forwarding ?
mc_forwarding AND
medium_id
proxy_arp OR
shared_media OR
secure_redirects OR
send_redirects OR
bootp_relay AND
accept_source_route AND
rp_filter AND
arp_filter OR
arp_announce MAX
arp_ignore MAX
arp_accept
app_solicit
disable_policy
disable_xfrm
tag
(see include/linux/inetdevice.h:83 for IN_DEV_{AND,OR,MAX}CONF)

Putting a new value in "all" doesn't change the value you read from
"$interface", but it only gets computed and used internally.

BYtE
Philipp
--
/ / (_)__ __ ____ __ Philipp Hahn
/ /__/ / _ \/ // /\ \/ /
/____/_/_//_/\_,_/ /_/\_\ [email protected]

2009-03-03 19:28:17

by martin f krafft

[permalink] [raw]
Subject: Re: /proc/sys/net/ip*/conf/all/* does not actually affect interfaces

also sprach Philipp Matthias Hahn <[email protected]> [2009.03.03.0800 +0100]:
> "all" on the other hand allways gets applied in addition to the current
> setting, but it depends on the exact setting, if its ORed, ANDed, or
> whatevered:
[...]

Oh wow. This is very underdocumented. Thanks Philipp for taking the
time to reply!

The only reference I could find was

http://lkml.indiana.edu/hypermail/linux/kernel/0103.0/0440.html

which was unanswered.

Can anyone recall the rationale for this somewhat complex-seeming
solution?

I suppose the goal is to allow all/* to override (which would be the
right solution). However, it depends on whether the default is 0 or
1 on whether to AND or OR. Example:

> log_martians OR

default off, to turn it on globally, I just need to set all=1 and
the OR takes care of it.

> rp_filter AND

default on, but to disable it globally (set all=0), it needs the
AND.

> (see include/linux/inetdevice.h:83 for IN_DEV_{AND,OR,MAX}CONF)

Unfortunately, that's just ipv4/conf/* and I cannot seem to find the
ipv6/conf/* counterparts.

> Putting a new value in "all" doesn't change the value you read
> from "$interface", but it only gets computed and used internally.

Hm, that clears it up... kinda. It does *not* explain by the RAs
were still accepted (ipv6.conf.all.accept_ra and .autoconf where
both 0), so unless those values are (wrongly) OR'd, I will need to
investigate this.

I will also work on patches to fix the documentation of this, and
that involves the kernel source as well as e.g. the IPv6 HOWTO and
other docs and manpages.

But to do this, I'd really like to know a bit more about the design
motivation. Anyone?

--
martin | http://madduck.net/ | http://two.sentenc.es/

before he died, rabbi zusya said: "in the world to come they will not
ask me, 'why were you not moses?' they will ask me, 'why were you not
zusya?'"

spamtraps: [email protected]


Attachments:
(No filename) (1.89 kB)
digital_signature_gpg.asc (197.00 B)
Digital signature (see http://martin-krafft.net/gpg/)
Download all attachments

2009-03-04 13:35:18

by Philipp Matthias Hahn

[permalink] [raw]
Subject: Re: /proc/sys/net/ip*/conf/all/* does not actually affect interfaces

Hello Martin!

On Tue, Mar 03, 2009 at 08:27:47PM +0100, martin f krafft wrote:
> also sprach Philipp Matthias Hahn <[email protected]> [2009.03.03.0800 +0100]:

> > Putting a new value in "all" doesn't change the value you read
> > from "$interface", but it only gets computed and used internally.
>
> Hm, that clears it up... kinda. It does *not* explain by the RAs
> were still accepted (ipv6.conf.all.accept_ra and .autoconf where
> both 0), so unless those values are (wrongly) OR'd, I will need to
> investigate this.

I took another look at
http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=blob;f=include/linux/inetdevice.h;hb=HEAD#l102

102 #define IN_DEV_RX_REDIRECTS(in_dev) \
103 ((IN_DEV_FORWARD(in_dev) && \
104 IN_DEV_ANDCONF((in_dev), ACCEPT_REDIRECTS)) \
105 || (!IN_DEV_FORWARD(in_dev) && \
106 IN_DEV_ORCONF((in_dev), ACCEPT_REDIRECTS)))

"accept_redirect" depends on "forwarding": If forwarding is enabled,
it's ANDed, if it's disabled, it's ORed.

> > "all" on the other hand allways gets applied in addition to the current
> > setting, but it depends on the exact setting, if its ORed, ANDed, or
> > whatevered:
> [...]
>
> Oh wow. This is very underdocumented.

Yes, I only can agree with you.

BYtE
Phhilipp Hahn
--
/ / (_)__ __ ____ __ Philipp Hahn
/ /__/ / _ \/ // /\ \/ /
/____/_/_//_/\_,_/ /_/\_\ [email protected]