-
Notifications
You must be signed in to change notification settings - Fork 173
router: check src/dst IA, check transit source IP #4157
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
ac78e61
to
61437fe
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewable status: 0 of 10 files reviewed, 1 unresolved discussion (waiting on @FR4NK-W and @matzf)
router/dataplane.go, line 1265 at r1 (raw file):
if p.path.IsXover() { if r, err := p.doXover(); err != nil {
Should the validateHopExpiry
and verifyCurrentMAC
checks done after a Xover info and HF update also be moved here with the other validations?
Code quote:
p.doXover()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewable status: 0 of 10 files reviewed, 1 unresolved discussion (waiting on @FR4NK-W)
router/dataplane.go, line 1265 at r1 (raw file):
Previously, FR4NK-W wrote…
Should the
validateHopExpiry
andverifyCurrentMAC
checks done after a Xover info and HF update also be moved here with the other validations?
Good point, thanks! Done.
9af31f4
to
c42e0eb
Compare
e5058c9
to
ec40080
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewable status: 0 of 10 files reviewed, 3 unresolved discussions (waiting on @lukedirtwalker and @matzf)
router/dataplane.go
line 110 at r4 (raw file):
var ( alreadySet = serrors.New("already set") invalidSrcIA = serrors.New("invalid source IA")
Suggestion:
ISD-AS
router/dataplane.go
line 111 at r4 (raw file):
alreadySet = serrors.New("already set") invalidSrcIA = serrors.New("invalid source IA") invalidDstIA = serrors.New("invalid destination IA")
Suggestion:
ISD-AS
router/dataplane.go
line 915 at r4 (raw file):
pktIngressID := p.ingressInterface() expectedSrc, ok := p.d.internalNextHops[pktIngressID] if !ok || !expectedSrc.IP.Equal(p.srcAddr.IP) || expectedSrc.Port != p.srcAddr.Port {
I think you should only check the IP address, but not the port here.
Checking the port prohibits source port randomization that could be used for load balancing (e.g., in LAG or ECMP)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewable status: 0 of 10 files reviewed, 3 unresolved discussions (waiting on @lukedirtwalker and @oncilla)
router/dataplane.go
line 110 at r4 (raw file):
var ( alreadySet = serrors.New("already set") invalidSrcIA = serrors.New("invalid source IA")
Done.
router/dataplane.go
line 111 at r4 (raw file):
alreadySet = serrors.New("already set") invalidSrcIA = serrors.New("invalid source IA") invalidDstIA = serrors.New("invalid destination IA")
Done.
router/dataplane.go
line 915 at r4 (raw file):
Previously, oncilla (Dominik Roos) wrote…
I think you should only check the IP address, but not the port here.
Checking the port prohibits source port randomization that could be used for load balancing (e.g., in LAG or ECMP)
Done, ok for me.
Just for the record, the behavior is different for the intra-AS links, where this router implementation uses a dialed UDP connection and consequently (implicitly) checks the source port as well.
28bdfbc
to
fae6858
Compare
fae6858
to
86dab5d
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewable status: 0 of 10 files reviewed, 4 unresolved discussions (waiting on @lukedirtwalker and @oncilla)
a discussion (no related file):
Ping @oncilla, is this ok for you now?
86dab5d
to
e110b35
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewed 2 of 10 files at r1, 1 of 1 files at r6, all commit messages.
Reviewable status: 3 of 10 files reviewed, 6 unresolved discussions (waiting on @matzf and @oncilla)
pkg/slayers/path/scion/base.go
line 99 at r6 (raw file):
func (s *Base) infIndexForHF(hf uint8) uint8 { if s.NumINF >= 2 {
I think we could just make a switch out of this:
switch {
case s.NumINF >= 1 && hf < s.PathMeta.SegLen[0]:
return 0
case s.NumINF >= 2 && hf < s.PathMeta.SegLen[0]+s.PathMeta.SegLen[1]:
return 1
default:
return uint8(s.NumINF - 1)
}
router/dataplane.go
line 912 at r6 (raw file):
// SrcIA checks by disguising packets as transit traffic. func (p *scionPacketProcessor) validateTransitUnderlaySrc() (processResult, error) { if p.ingressID == 0 && !p.path.IsFirstHop() {
you could use an early return here, for less indentation in the remaining code.
if p.path.IsFirstHop() || p.ingressID != 0 {
return processResult{},nil
}
bc59b38
to
a5f1abd
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewable status: 1 of 11 files reviewed, 6 unresolved discussions (waiting on @lukedirtwalker and @oncilla)
pkg/slayers/path/scion/base.go
line 99 at r6 (raw file):
Previously, lukedirtwalker (Lukas Vogel) wrote…
I think we could just make a switch out of this:
switch { case s.NumINF >= 1 && hf < s.PathMeta.SegLen[0]: return 0 case s.NumINF >= 2 && hf < s.PathMeta.SegLen[0]+s.PathMeta.SegLen[1]: return 1 default: return uint8(s.NumINF - 1) }
Good idea, thanks!
I opted to completely omit the NumINF
checks and rely entirely on SegLen
. This changes the behavior for out of range hf
values (returns 2 instead of NumINF-1), so that the range check needs to be done at the caller (only for IsXover
, other callers already check sufficiently). IMO this makes quite a bit easier to understand, also for IsXover
.
router/dataplane.go
line 912 at r6 (raw file):
Previously, lukedirtwalker (Lukas Vogel) wrote…
you could use an early return here, for less indentation in the remaining code.
if p.path.IsFirstHop() || p.ingressID != 0 { return processResult{},nil }
Good idea, thanks. Done.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewed 2 of 2 files at r7, 1 of 1 files at r9.
Reviewable status: 3 of 11 files reviewed, 5 unresolved discussions (waiting on @matzf and @oncilla)
pkg/slayers/path/scion/base.go
line 99 at r6 (raw file):
Previously, matzf (Matthias Frei) wrote…
Good idea, thanks!
I opted to completely omit theNumINF
checks and rely entirely onSegLen
. This changes the behavior for out of rangehf
values (returns 2 instead of NumINF-1), so that the range check needs to be done at the caller (only forIsXover
, other callers already check sufficiently). IMO this makes quite a bit easier to understand, also forIsXover
.
couldn't you run into panics if the segments is invalid? i.e. accessing the SegLen out of bounds?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewable status: 3 of 11 files reviewed, 5 unresolved discussions (waiting on @lukedirtwalker and @oncilla)
pkg/slayers/path/scion/base.go
line 99 at r6 (raw file):
Previously, lukedirtwalker (Lukas Vogel) wrote…
couldn't you run into panics if the segments is invalid? i.e. accessing the SegLen out of bounds?
No, I think not; SegLen
is a fixed size array [3]uint8
.
Add egress filtering on the source IA to mitigate accidental or malicious source address spoofing by untrusted end-hosts. Compring the source IA against the configured local IA for egress packets is fast and reliable. A malicious end host could bypass this source IA check relatively easily; by prepending fake hop-fields, it can masquerade it's outgoing packets as transit packets, for which the check is not applied. To mitigate this form of spoofing attack, we add a check to for the source IP address of transit traffic -- if this source IP doesn't match the IP address of the corresponding sibling border router, the packet is silently dropped. Under reasonable the assumption that the underlying (IP-)network infrastructure prevents untrusted end-hosts from spoofing IP addresses of the SCION infrastructure hosts, this check prevents source IA spoofing. As a natural extension of the source IA checks for outgoing traffic, we also add checks for source/destination IA for transit and incoming packets; - for transit traffic: neither source nor destination IA must equal local IA - for incoming packets: source IA must NOT equal local IA destination IA must equal local IA - for incoming packets: source IA must equal local IA destination IA must NOT equal local IA If any check fails, we reply with the appropriate SCMP Error InvalidSourceAddress/InvalidDestinationAddress. Observe that in case of InvalidSourceAddress, the correct destination IA for the SCMP Error message is unknown. It's thus possible that the error message will be dropped because of an invalid destination IA on the way to the back to the originator. We have all information needed to extend these source/destination IA checks to packets that originate from or are destined to direct neighbors. However, this would not provide additional tamper-resistance; if the neighbor AS is benign, it will perform filtering on its own. In case the neighbor AS is malicious, it could trivially bypass such a filter by prepending fake hop fields. Add router acceptance test cases for these new checks. Multiple existing test cases needed to be adapted because the input packet accidentally failed some of the new checks.
78bf780
to
a7f3755
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewed 1 of 1 files at r8, all commit messages.
Reviewable status: 4 of 11 files reviewed, 4 unresolved discussions (waiting on @oncilla)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewed 6 of 10 files at r1, 1 of 2 files at r2, 1 of 1 files at r3, 1 of 2 files at r7, 1 of 1 files at r8, 1 of 1 files at r9, all commit messages.
Reviewable status: all files reviewed, 1 unresolved discussion (waiting on @FR4NK-W and @lukedirtwalker)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewed 5 of 10 files at r1, 1 of 2 files at r2, 1 of 1 files at r3.
Reviewable status:complete! all files reviewed, all discussions resolved (waiting on @matzf)
Add egress filtering on the source IA to mitigate accidental or malicious source address spoofing by untrusted end-hosts. Comparing the source IA against the configured local IA for egress packets is fast and reliable. A malicious end host could bypass this source IA check relatively easily; by prepending fake hop-fields, it can masquerade its outgoing packets as transit packets, for which the check is not applied. To mitigate this form of spoofing attack, we add a check to for the source IP address of transit traffic -- if this source IP doesn't match the IP address of the corresponding sibling border router, the packet is silently dropped. Under the reasonable assumption that the underlying (IP-)network infrastructure prevents untrusted end-hosts from spoofing IP addresses of the SCION infrastructure hosts, this check prevents source IA spoofing. As a natural extension of the source IA checks for outgoing traffic, we also add checks for source/destination IA for transit and incoming packets; - for transit traffic: neither source nor destination IA must equal local IA - for incoming packets: source IA must NOT equal local IA destination IA must equal local IA - for outgoing packets: source IA must equal local IA destination IA must NOT equal local IA If any check fails, we reply with the appropriate SCMP Error InvalidSourceAddress/InvalidDestinationAddress. Observe that in case of InvalidSourceAddress, the correct destination IA for the SCMP Error message is unknown. It's thus possible that the error message will be dropped because of an invalid destination IA on the way back to the originator. We have all information needed to extend these source/destination IA checks to packets that originate from or are destined to direct neighbors. However, this would not provide additional tamper-resistance; if the neighbor AS is benign, it will perform filtering on its own. In case the neighbor AS is malicious, it could trivially bypass such a filter by prepending fake hop fields. Add router acceptance test cases for these new checks. Multiple existing test cases needed to be adapted because the input packet accidentally failed some of the new checks.
Add egress filtering on the source IA to mitigate accidental or
malicious source address spoofing by untrusted end-hosts.
Comparing the source IA against the configured local IA for egress
packets is fast and reliable.
A malicious end host could bypass this source IA check relatively
easily; by prepending fake hop-fields, it can masquerade its outgoing
packets as transit packets, for which the check is not applied.
To mitigate this form of spoofing attack, we add a check to for the
source IP address of transit traffic -- if this source IP doesn't match
the IP address of the corresponding sibling border router, the packet is
silently dropped.
Under the reasonable assumption that the underlying (IP-)network
infrastructure prevents untrusted end-hosts from spoofing IP addresses
of the SCION infrastructure hosts, this check prevents source IA
spoofing.
As a natural extension of the source IA checks for outgoing traffic,
we also add checks for source/destination IA for transit and incoming packets;
neither source nor destination IA must equal local IA
source IA must NOT equal local IA
destination IA must equal local IA
source IA must equal local IA
destination IA must NOT equal local IA
If any check fails, we reply with the appropriate SCMP Error
InvalidSourceAddress/InvalidDestinationAddress.
Observe that in case of InvalidSourceAddress, the correct destination IA
for the SCMP Error message is unknown. It's thus possible that the error
message will be dropped because of an invalid destination IA on the
way back to the originator.
We have all information needed to extend these source/destination IA
checks to packets that originate from or are destined to direct neighbors.
However, this would not provide additional tamper-resistance; if the
neighbor AS is benign, it will perform filtering on its own. In case the
neighbor AS is malicious, it could trivially bypass such a filter by
prepending fake hop fields.
Add router acceptance test cases for these new checks.
Multiple existing test cases needed to be adapted because the input
packet accidentally failed some of the new checks.
This change is