vyos-1x icon indicating copy to clipboard operation
vyos-1x copied to clipboard

ndp-proxy: T2898: Add service ndp-proxy

Open hensur opened this issue 3 years ago • 22 comments

Change Summary

This builts on https://github.com/vyos/vyos-1x/pull/556

While the previous PR was superseded by the nat66 implementation, this change allows for configuration of the proxy apart from the nat66 configuration.

Types of changes

  • [ ] Bug fix (non-breaking change which fixes an issue)
  • [ ] New feature (non-breaking change which adds functionality)
  • [ ] Code style update (formatting, renaming)
  • [ ] Refactoring (no functional changes)
  • [ ] Migration from an old Vyatta component to vyos-1x, please link to related PR inside obsoleted component
  • [x] Other (please describe): New feature, but changing behaviour of nat66 configuration. While previously the ndp proxy was configured for every nat66 source rule, this now has to be done manually. I'm not sure if this is the best way to handle this. I'm open for suggestions here.

Related Task(s)

  • https://phabricator.vyos.net/T2898

Component(s) name

service ndp-proxy

Proposed changes

Existing nat66 rules are migrated using a migration script, in order to not break currently working configurations.

This change however won't create ndp proxy entries for new nat66 rules.

This was done in the background before, as the nat66 script owned the ndppd configuration. Now, apart from migrated configurations, this has to be done manually. The ndppd config doesn't seem to support includes, and writing to the ndppd config from two scripts could become quite ugly. If there were the possiblity to write to set other configuration elements from another config section's apply method, it could be a possible workaround. But I'm not sure if that is wanted here.

It might actually be fine to not configure ndppd automatically. If I understand the feature correctly, there might actually be cases where the source prefix is already routed to vyos and one doesn't have to proxy NDP messages.

How to test

set service ndp-proxy interface eth0 prefix 2001:db8:126::/64 disable
set service ndp-proxy interface eth0 prefix 2001:db8:126::/64 mode 'static'
cat /run/ndppd/ndppd.conf
########################################################
#
# autogenerated by ndp_proxy.py
#
########################################################


proxy eth0 {
    router yes
    timeout 500
    ttl 30000
    rule 2001:db8:126::/64 {
        static
    }
}

Checklist:

  • [x] I have read the CONTRIBUTING document
  • [x] I have linked this PR to one or more Phabricator Task(s)
  • [x] I have run the components SMOKETESTS if applicable
  • [x] My commit headlines contain a valid Task id
  • [x] My change requires a change to the documentation
  • [ ] I have updated the documentation accordingly

hensur avatar Jan 09 '22 18:01 hensur

Can you maybe elaborate a bit more why this change is required? Moving it to a dedicated CLI node is okay for me as long as the current config is properly migrated. We only need to warn the user that ndp-proxy configuration is required when new nat66 rules are added.

c-po avatar Jan 10 '22 09:01 c-po

@c-po In my case, I have a server in a shared /48 network, from which im allowed to use a single /64. I want to provide different VM Networks with /80 portions of this /64. Since the network is not directly routed to my server, I have to proxy NDP messages between the uplink interface and the VM Networks for IPv6 to work.

hensur avatar Jan 10 '22 10:01 hensur

Related to this new feature, I'd like to propose a patch to the ndppd version currently in use by vyos. The upstream hasn't had any releases lately, and there seems to be a bug where ndppd will always read the full IPv6 Routing Table. This is actually not required unless any prefixes are configured with the auto mode.

While this might be fine on a more standard debian installation, it has caused some issues for me with routers that also hold a BGP Full Table. In this case, ndppd takes forever to go through all possible routes.

This is the upstream fix for the issue, I already prepared a patch that only adds the any_auto() check. If I understand correctly, this would have to be added to https://github.com/vyos/vyos-build/tree/current/packages ? https://github.com/DanielAdolfsson/ndppd/commit/8a8f7b065c38d6180965919ee7cf8ee9a7515400

hensur avatar Jan 10 '22 10:01 hensur

@hensur Do you plan to improve the NDPPD service that NAT66 relies on?

jack9603301 avatar Jan 11 '22 01:01 jack9603301

@c-po In my case, I have a server in a shared /48 network, from which im allowed to use a single /64. I want to provide different VM Networks with /80 portions of this /64. Since the network is not directly routed to my server, I have to proxy NDP messages between the uplink interface and the VM Networks for IPv6 to work.

So this is actually IPv6 proxy-arp ;)? Sounds like a legitimate use-case

c-po avatar Jan 11 '22 09:01 c-po

This is the upstream fix for the issue, I already prepared a patch that only adds the any_auto() check. If I understand correctly, this would have to be added to https://github.com/vyos/vyos-build/tree/current/packages ? DanielAdolfsson/ndppd@8a8f7b0

If the patch is merged in the upstream repo it will be fairly easy to consume this commit for building. Latest addition to source builds was keepalived https://github.com/vyos/vyos-build/tree/current/packages/keepalived

The only remainder which still makes my head scratch is - how to tell the system that I need ndpd for IPv6 proxy-arp equivalent or for nat66? - We should come up with a simple CLI not causing more headaches to the user. Maybe we need a broker agent like what vyos-hostsd is doing so we can send messages to the broker and inform him which interfaces/prefixes got added/removed. Then we can configure this on an interface level and also on the nat66 level.

c-po avatar Jan 11 '22 09:01 c-po

So this is actually IPv6 proxy-arp ;)? Sounds like a legitimate use-case

Yes, that is actually a way simpler explanation. :) Don't know why I didn't think of this.

hensur avatar Jan 11 '22 10:01 hensur

The only remainder which still makes my head scratch is - how to tell the system that I need ndpd for IPv6 proxy-arp equivalent or for nat66? - We should come up with a simple CLI not causing more headaches to the user. Maybe we need a broker agent like what vyos-hostsd is doing so we can send messages to the broker and inform him which interfaces/prefixes got added/removed. Then we can configure this on an interface level and also on the nat66 level.

That sounds like a good solution. Does it have to be this "stateful"? Can't we just make it read two json/yaml files, each containing a list of prefixes for a interface, something like this:

# ndp-proxy.yaml
eth0:
  - prefix: fc00::/64
    mode: iface
    iface: eth1
# nat66.yaml
eth0:
  - prefix: fc10::/64
    mode: static

Then merge both yaml dicts and generate a ndppd.conf from all inputs. This would make things a lot simpler, I think. Either nat66 or ndp-proxy would then just write to their respective config file and reload the daemon, which would in turn restart ndppd.

hensur avatar Jan 11 '22 10:01 hensur

@hensur Do you plan to improve the NDPPD service that NAT66 relies on?

@jack9603301 I'm not sure what you mean by "improve"? Is this related to the patch or this change in general? The patch would look like this: https://gist.github.com/hensur/a3e21f0b2fba08883460bf82bb9f6278

Mainly, I'd like to be able to configure ndppd apart from nat66 though. Using a broker like @c-po suggested would also make sure that things don't change for the nat66 implementation.

hensur avatar Jan 11 '22 10:01 hensur

Related vyos-build PR: https://github.com/vyos/vyos-build/pull/212

hensur avatar Jan 11 '22 12:01 hensur

@hensur Do you plan to improve the NDPPD service that NAT66 relies on?

@jack9603301 I'm not sure what you mean by "improve"? Is this related to the patch or this change in general? The patch would look like this: https://gist.github.com/hensur/a3e21f0b2fba08883460bf82bb9f6278

Mainly, I'd like to be able to configure ndppd apart from nat66 though. Using a broker like @c-po suggested would also make sure that things don't change for the nat66 implementation.

Nat66 automatically generates NDPPD, I mean, do you want to separate the implementation of NDPPD?

jack9603301 avatar Jan 13 '22 19:01 jack9603301

@jack9603301 Yes, I want to be able to configure ndp proxy entries without using nat66. But with @c-po 's suggestions, both should be able to configure ndppd.

hensur avatar Jan 13 '22 21:01 hensur

That sounds like a good solution. Does it have to be this "stateful"? Can't we just make it read two json/yaml files, each containing a list of prefixes for a interface, something like this:

Who would be responsible for merging the yamls and render the ndppd config?

c-po avatar Jan 13 '22 21:01 c-po

Who would be responsible for merging the yamls and render the ndppd config?

Oh, I think we could still use some sort of broker agent for that. I would just like to have a simple one, that just merges the yamls and renders the config. vyos-hostsd seems to be quite complex, I wouldn't want to write a whole JSON API to add/update/delete the ndppd prefixes.

hensur avatar Jan 13 '22 22:01 hensur

@jack9603301 Yes, I want to be able to configure ndp proxy entries without using nat66. But with @c-po 's suggestions, both should be able to configure ndppd.

Why not implement a background service script to update the NDPPD configuration, using the YAML configuration file, which I agree with the previous suggestion

jack9603301 avatar Jan 18 '22 17:01 jack9603301

The only remainder which still makes my head scratch is - how to tell the system that I need ndpd for IPv6 proxy-arp equivalent or for nat66? - We should come up with a simple CLI not causing more headaches to the user. Maybe we need a broker agent like what vyos-hostsd is doing so we can send messages to the broker and inform him which interfaces/prefixes got added/removed. Then we can configure this on an interface level and also on the nat66 level.

That sounds like a good solution. Does it have to be this "stateful"? Can't we just make it read two json/yaml files, each containing a list of prefixes for a interface, something like this:

# ndp-proxy.yaml
eth0:
  - prefix: fc00::/64
    mode: iface
    iface: eth1
# nat66.yaml
eth0:
  - prefix: fc10::/64
    mode: static

Then merge both yaml dicts and generate a ndppd.conf from all inputs. This would make things a lot simpler, I think. Either nat66 or ndp-proxy would then just write to their respective config file and reload the daemon, which would in turn restart ndppd.

I think this configuration structure is not easy to parse correctly, as follows:

# ndp-proxy.yaml
global:
  - eth0:
      - prefix: fc00::/64
        mode: iface
        iface: eth1
# nat66.yaml
nat66:
  - eth0:
      - prefix: fc10::/64
        mode: static

jack9603301 avatar Jan 21 '22 09:01 jack9603301

@jack9603301 I think it might be easier to handle if both nat66 and ndp write to separate files. This should help to prevent any race conditions that might occur.

hensur avatar Jan 21 '22 12:01 hensur

@jack9603301 I think it might be easier to handle if both nat66 and ndp write to separate files. This should help to prevent any race conditions that might occur.

I was wondering if I could submit code directly to your PR, if so I might try writing Python daemon scripts (when I have time)

I agree with you about your idea

jack9603301 avatar Jan 21 '22 17:01 jack9603301

I've already written a conversion script, and maybe now I just need a daemon execution 图片 图片

jack9603301 avatar Jan 22 '22 06:01 jack9603301

This is just a rough draft that combines two or more YAMLs correctly into one, but still needs to explore how to combine with Vyos and write daemons 图片

There are the following solutions:

  1. Use a daemon to periodically detect the NDPPD restart (not recommended)
  2. Use this conversion script to work with the unwritten YAML to NDPPD script, and always restart NDPPD every time you change NAT66 or NDP-Proxy
  3. The same as 2, but the configuration script conversion program from YAML to NDPPD is merged with the configuration script of NAT66 and NDP-Proxy.

jack9603301 avatar Jan 22 '22 06:01 jack9603301

I was wondering if I could submit code directly to your PR

You should be able to create a PR in my Repo. I'll just merge that into this branch then. :)

Regarding the possible solutions: I'm still not sure what would be the best way to do the reconfiguration. I think having a python script that merges both yaml files and templates the ndppd.conf with those is a good first step!

We just have to figure out how to invoke it. Another option would be to just integrate it with the ndppd systemd unit. We could invoke the generator script using ExecStartPre= and just keep restarting ndppd in both the nat66 and ndp-proxy sections.

hensur avatar Jan 22 '22 18:01 hensur

This pull request has conflicts, please resolve those before we can evaluate the pull request.

github-actions[bot] avatar Apr 15 '22 18:04 github-actions[bot]

Is anyone working on it? Or can it be closed? There is no activity and no updates.

sever-sever avatar Dec 08 '23 21:12 sever-sever

Will be revisited in an upcoming PR soon

c-po avatar Dec 17 '23 16:12 c-po