Skip to content
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

No DNS servers are queried and passed to updown script with dns_handler option enabled #1320

Open
oldium opened this issue Sep 30, 2022 · 24 comments
Labels

Comments

@oldium
Copy link

oldium commented Sep 30, 2022

System (please complete the following information):

  • OS: Docker/Alpine (custom Dockerfile building from master)
  • strongSwan version(s): Git master
  • Tested/confirmed with the latest version: yes

All modifications present in this bug report are in this repository: https://github.com/oldium/strongswan

Describe the bug
The updown script's dns_handler option does not work, the DNS servers are (1) not queried and (2) not passed to script.

To Reproduce
Steps to reproduce the behavior (load_modular = yes):

  1. Set charon.plugins.updown.dns_handler = yes
  2. Set charon.plugins.resolve.load = no
  3. Try to connect to IKEv2 VPN.
  4. Check logs for DNS - whether it contains PLUTO_DNS values and whether the VPN request contained DNS values.
  5. Observe that the logs do not contain anything about DNS.

Expected behavior
DNS are queried and passed to updown script.

Analysis
I updated the code and added log to updown plugin to indicate that the dns_handler option was enabled and also to the attribute handler to see whether the DNS was remembered by the plugin. Observations:

  1. Without resolve plugin there is actually nothing, the DNS servers are not even queried by the request to VPN server:

    strongswan  | 00[CFG] enabling DNS handler for updown plugin
    
  2. With resolve plugin the DNS are queried, but nothing goes to the updown plugin:

    strongswan  | 00[CFG] enabling DNS handler for updown plugin
    strongswan  | 05[IKE] building INTERNAL_IP4_DNS attribute
    strongswan  | 05[IKE] building INTERNAL_IP6_DNS attribute
    strongswan  | 05[ENC] generating IKE_AUTH request 1 [ IDi CERT CERTREQ IDr AUTH CPRQ(ADDR ADDR6 DNS DNS6) SA TSi TSr N(MOBIKE_SUP) N(NO_ADD_ADDR) N(EAP_ONLY) N(MSG_ID_SYN_SUP) ]
    strongswan  | 04[ENC] parsed IKE_AUTH response 1 [ IDr CERT AUTH N(CRASH_DET) CPRP(ADDR DNS DNS DNS) SA TSi TSr N(ESP_TFC_PAD_N) N(NON_FIRST_FRAG) ]
    strongswan  | 04[IKE] processing INTERNAL_IP4_DNS attribute
    strongswan  | 04[IKE] installing DNS server x.y.z.5 to /etc/resolv.conf
    strongswan  | 04[IKE] processing INTERNAL_IP4_DNS attribute
    strongswan  | 04[IKE] installing DNS server x.y.z.195 to /etc/resolv.conf
    strongswan  | 04[IKE] processing INTERNAL_IP4_DNS attribute
    strongswan  | 04[IKE] installing DNS server x.y.z.2 to /etc/resolv.conf
    

Ok, there had to be something wrong. I figured out that the IKE code (ike_config.c) queries only attributes required by any plugin, so I copied the create_attribute_enumerator code from resolve plugin into updown plugin. Now it is better:

  1. Without resolve plugin, but with updown plugin extended by create_attribute_enumerator:

    strongswan  | 00[CFG] enabling DNS handler for updown plugin
    strongswan  | 16[IKE] building INTERNAL_IP4_DNS attribute
    strongswan  | 16[IKE] building INTERNAL_IP6_DNS attribute
    strongswan  | 16[ENC] generating IKE_AUTH request 1 [ IDi CERT CERTREQ IDr AUTH CPRQ(ADDR ADDR6 DNS DNS6) SA TSi TSr N(MOBIKE_SUP) N(NO_ADD_ADDR) N(EAP_ONLY) N(MSG_ID_SYN_SUP) ]
    strongswan  | 07[ENC] parsed IKE_AUTH response 1 [ IDr CERT AUTH N(CRASH_DET) CPRP(ADDR DNS DNS DNS) SA TSi TSr N(ESP_TFC_PAD_N) N(NON_FIRST_FRAG) ]
    strongswan  | 07[IKE] processing INTERNAL_IP4_DNS attribute
    strongswan  | 07[IKE] remembering DNS server x.y.z.5 for updown script
    strongswan  | 07[IKE] processing INTERNAL_IP4_DNS attribute
    strongswan  | 07[IKE] remembering DNS server x.y.z.195 for updown script
    strongswan  | 07[IKE] processing INTERNAL_IP4_DNS attribute
    strongswan  | 07[IKE] remembering DNS server x.y.z.2 for updown script
    strongswan  | 07[CHD] updown: PLUTO_DNS4_1='x.y.z.5'
    strongswan  | 07[CHD] updown: PLUTO_DNS4_2='x.y.z.195'
    strongswan  | 07[CHD] updown: PLUTO_DNS4_3='x.y.z.2'
    
  2. With resolve plugin and updown plugin extended by create_attribute_enumerator:

    strongswan  | 00[CFG] enabling DNS handler for updown plugin
    strongswan  | 05[IKE] building INTERNAL_IP4_DNS attribute
    strongswan  | 05[IKE] building INTERNAL_IP6_DNS attribute
    strongswan  | 05[IKE] building INTERNAL_IP4_DNS attribute
    strongswan  | 05[IKE] building INTERNAL_IP6_DNS attribute
    strongswan  | 05[ENC] generating IKE_AUTH request 1 [ IDi CERT CERTREQ IDr AUTH CPRQ(ADDR ADDR6 DNS DNS6 DNS DNS6) SA TSi TSr N(MOBIKE_SUP) N(NO_ADD_ADDR) N(EAP_ONLY) N(MSG_ID_SYN_SUP) ]
    strongswan  | 04[ENC] parsed IKE_AUTH response 1 [ IDr CERT AUTH N(CRASH_DET) CPRP(ADDR DNS DNS DNS) SA TSi TSr N(ESP_TFC_PAD_N) N(NON_FIRST_FRAG) ]
    strongswan  | 04[IKE] processing INTERNAL_IP4_DNS attribute
    strongswan  | 04[IKE] installing DNS server x.y.z.5 to /etc/resolv.conf
    strongswan  | 04[IKE] processing INTERNAL_IP4_DNS attribute
    strongswan  | 04[IKE] remembering DNS server x.y.z.195 for updown script
    strongswan  | 04[IKE] processing INTERNAL_IP4_DNS attribute
    strongswan  | 04[IKE] installing DNS server x.y.z.2 to /etc/resolv.conf
    strongswan  | 04[CHD] updown: PLUTO_DNS4_1='x.y.z.195'
    

This means that the DNS querying with updown plugin does not work:

  1. In unmodified code, when resolve and updown plugins are both enabled, the resolve plugin takes all DNS queries. The updown plugin does not see any DNS (which is in contrast with documentation, which states that everything should go to updown plugin).
  2. When updown plugin is updated with DNS attribute registration, both resolve and updown plugins cannot coexist, because (1) the IKE request contains DNS and DNS6 request twice (which looks like a bug in ike_config.c) and (2) one plugin eats some DNS servers and the other the rest.

Moreover, checking /etc/resolv.conf discovered that only one DNS server (the last one) is preserved, so also the resolve plugin does not work correctly.

@oldium oldium changed the title No DNS servers are queried and passed to updown script No DNS servers are queried and passed to updown script with dns_handler option enabled Sep 30, 2022
@tobiasbrunner
Copy link
Member

I guess, for this to work, you have to change the order of the plugins. That is, you want to increase the priority of the updown plugin so it's loaded before the resolve plugin and will process the received DNS servers before the latter.

Note that when this feature of the updown plugin was added 10 years ago, it was most likely meant to be used with disabled resolve plugin but in combination with the stroke plugin's feature to request, but not process, DNS servers per config (leftdns option, there is currently no equivalent for vici/swanctl).

@tobiasbrunner tobiasbrunner removed the new label Oct 3, 2022
@oldium
Copy link
Author

oldium commented Oct 3, 2022

I compiled it again with just logging enhancements of updown plugin, I gave it priority 2 while the resolve plugin had priority 1.

Grep for DNS in logs:

strongswan  | 00[CFG] enabling DNS handler for updown plugin
strongswan  | 16[IKE] building INTERNAL_IP4_DNS attribute
strongswan  | 16[IKE] building INTERNAL_IP6_DNS attribute
strongswan  | 16[ENC] generating IKE_AUTH request 1 [ IDi CERT CERTREQ IDr AUTH CPRQ(ADDR ADDR6 DNS DNS6) SA TSi TSr N(MOBIKE_SUP) N(NO_ADD_ADDR) N(EAP_ONLY) N(MSG_ID_SYN_SUP) ]
strongswan  | 13[ENC] parsed IKE_AUTH response 1 [ IDr CERT AUTH N(CRASH_DET) CPRP(ADDR DNS DNS DNS) SA TSi TSr N(ESP_TFC_PAD_N) N(NON_FIRST_FRAG) ]
strongswan  | 13[IKE] processing INTERNAL_IP4_DNS attribute
strongswan  | 13[IKE] installing DNS server x.y.z.5 to /etc/resolv.conf
strongswan  | 13[IKE] processing INTERNAL_IP4_DNS attribute
strongswan  | 13[IKE] remembering DNS server x.y.z.195 for updown script
strongswan  | 13[IKE] processing INTERNAL_IP4_DNS attribute
strongswan  | 13[IKE] remembering DNS server x.y.z.2 for updown script
strongswan  | 13[CHD] updown: PLUTO_DNS4_1='x.y.z.195'
strongswan  | 13[CHD] updown: PLUTO_DNS4_2='x.y.z.2'

The updown script sees 2 out of 3 DNS servers.

@tobiasbrunner
Copy link
Member

Interesting. Yeah, I guess the first is assigned directly because it was explicitly requested by the resolve plugin. The stroke plugin avoided that by not implementing the handle() method (or rather always returning FALSE) so other handlers receive all the attributes.

@oldium
Copy link
Author

oldium commented Oct 3, 2022

I am using swanctl, is there a workaround for this? I just want to get all DNS servers when the updown script is called. Also the resolve plugin in default-priority configuration stores just one DNS server into resolv.conf - only the last one.

strongswan  | 00[CFG] enabling DNS handler for updown plugin
strongswan  | 14[IKE] building INTERNAL_IP4_DNS attribute
strongswan  | 14[IKE] building INTERNAL_IP6_DNS attribute
strongswan  | 14[ENC] generating IKE_AUTH request 1 [ IDi CERT CERTREQ IDr AUTH CPRQ(ADDR ADDR6 DNS DNS6) SA TSi TSr N(MOBIKE_SUP) N(NO_ADD_ADDR) N(EAP_ONLY) N(MSG_ID_SYN_SUP) ]
strongswan  | 07[ENC] parsed IKE_AUTH response 1 [ IDr CERT AUTH N(CRASH_DET) CPRP(ADDR DNS DNS DNS) SA TSi TSr N(ESP_TFC_PAD_N) N(NON_FIRST_FRAG) ]
strongswan  | 07[IKE] processing INTERNAL_IP4_DNS attribute
strongswan  | 07[IKE] installing DNS server x.y.z.5 to /etc/resolv.conf
strongswan  | 07[IKE] processing INTERNAL_IP4_DNS attribute
strongswan  | 07[IKE] installing DNS server x.y.z.195 to /etc/resolv.conf
strongswan  | 07[IKE] processing INTERNAL_IP4_DNS attribute
strongswan  | 07[IKE] installing DNS server x.y.z.2 to /etc/resolv.conf
#> cat /etc/resolv.conf
nameserver x.y.z.2   # by strongSwan

The resolve plugin is also able to use resolveconf tool, so maybe it is able to set all DNS servers in that case.

@oldium
Copy link
Author

oldium commented Oct 3, 2022

Just to describe my goals, not the solution. Simply speaking - I need to connect two VPN endpoints. I have one fixed VPN connection (always on) and one for roadwarrior. The part of solution is to write custom updown scripts to (1) configure DNS for roadwarrior from the fixed VPN (the fixed VPN updown script), (2) setup routes to fixed VPN when roadwarrior connects (the roadwarrior updown script).

@tobiasbrunner
Copy link
Member

I am using swanctl, is there a workaround for this?

Perhaps via resolvconf (see below). Or you configure a custom path for resolv.conf (via charon.plugins.resolve.file) and parse the servers from there in your updown script.

I just want to get all DNS servers when the updown script is called.

What do you do with them?

Also the resolve plugin in default-priority configuration stores just one DNS server into resolv.conf - only the last one.

Hm, no idea why that would be the case (unless it somehow fails to read the original contents from the file to copy it - the plugin opens the old file, unlinks it and creates a new one it its place, then writes the new server and copies all content from the old file).

The resolve plugin is also able to use resolveconf tool, so maybe it is able to set all DNS servers in that case.

Might work better. I guess you could also write your own script that handles DNS servers that way (also see the 744-resolvconf branch and #744).

@tobiasbrunner
Copy link
Member

The part of solution is to write custom updown scripts to (1) configure DNS for roadwarrior from the fixed VPN (the fixed VPN updown script)

Configure where/how?

(2) setup routes to fixed VPN when roadwarrior connects (the roadwarrior updown script).

What routes exactly? Why are they not there yet when the "fixed" VPN is established?

@oldium
Copy link
Author

oldium commented Oct 3, 2022

The part of solution is to write custom updown scripts to (1) configure DNS for roadwarrior from the fixed VPN (the fixed VPN updown script)

Configure where/how?

I wanted to update the swanctl.conf configuration (the DNS pool for roadwarrior) and simply call swanctl --load-all from the updown script of fixed VPN.

(2) setup routes to fixed VPN when roadwarrior connects (the roadwarrior updown script).

What routes exactly? Why are they not there yet when the "fixed" VPN is established?

I meant update firewall to allow routing from roadwarrior subnet to fixed VPN subnet(s), also masquerade.

@oldium
Copy link
Author

oldium commented Oct 3, 2022

The resolve plugin is also able to use resolveconf tool, so maybe it is able to set all DNS servers in that case.

Might work better. I guess you could also write your own script that handles DNS servers that way (also see the 744-resolvconf branch and #744).

Works better with resolveconf (have not tried the branch yet), I am able to get all DNS configured directly from the updown script (with resolvconf -l. It looks like the DNS servers are not cleaned, though, because when I run swanctl --terminate fixed_vpn and then calling resolvconf -l from command line still shows all DNS servers.

@tobiasbrunner
Copy link
Member

The part of solution is to write custom updown scripts to (1) configure DNS for roadwarrior from the fixed VPN (the fixed VPN updown script)

Configure where/how?

I wanted to update the swanctl.conf configuration (the DNS pool for roadwarrior) and simply call swanctl --load-all from the updown script of fixed VPN.

(2) setup routes to fixed VPN when roadwarrior connects (the roadwarrior updown script).

What routes exactly? Why are they not there yet when the "fixed" VPN is established?

I meant update firewall to allow routing from roadwarrior subnet to fixed VPN subnet(s), also masquerade.

Sounds a bit hackish. Might be easier to use dnsmasq or similar as DNS proxy.

It looks like the DNS servers are not cleaned, though,

Check the logs.

@oldium
Copy link
Author

oldium commented Oct 3, 2022

Also the resolve plugin in default-priority configuration stores just one DNS server into resolv.conf - only the last one.

Hm, no idea why that would be the case (unless it somehow fails to read the original contents from the file to copy it - the plugin opens the old file, unlinks it and creates a new one it its place, then writes the new server and copies all content from the old file).

Maybe this is specific to Docker. Just a guess - the file /etc/resolv.conf is actually unlinked before being read, so this could be the reason why the reading fails. The read result is not checked nor logged, so I do not know exactly.

@oldium
Copy link
Author

oldium commented Oct 3, 2022

#> docker compose logs | grep DNS\\\|resolv
strongswan  | 00[LIB] plugin 'resolve': loaded successfully
strongswan  | 00[LIB] loading feature CUSTOM:resolve in plugin 'resolve'
strongswan  | 00[LIB] loaded plugins: charon aesni blowfish sha3 md4 mgf1 random nonce x509 revocation constraints acert pubkey pkcs1 pkcs7 pkcs12 pgp dnskey sshkey pem openssl pkcs8 fips-prf curve25519 chapoly xcbc cmac kdf gcm ntru drbg newhope curl files attr kernel-netlink resolve socket-default forecast farp vici updown eap-identity eap-md5 eap-mschapv2 eap-dynamic eap-radius eap-tls eap-ttls eap-peap eap-tnc tnc-tnccs dhcp whitelist lookip error-notify certexpire duplicheck addrblock counters
strongswan  | 05[IKE] building INTERNAL_IP4_DNS attribute
strongswan  | 05[IKE] building INTERNAL_IP6_DNS attribute
strongswan  | 05[ENC] generating IKE_AUTH request 1 [ IDi CERT CERTREQ IDr AUTH CPRQ(ADDR ADDR6 DNS DNS6) SA TSi TSr N(MOBIKE_SUP) N(NO_ADD_ADDR) N(EAP_ONLY) N(MSG_ID_SYN_SUP) ]
strongswan  | 14[ENC] parsed IKE_AUTH response 1 [ IDr CERT AUTH N(CRASH_DET) CPRP(ADDR DNS DNS DNS) SA TSi TSr N(ESP_TFC_PAD_N) N(NON_FIRST_FRAG) ]
strongswan  | 14[LIB] libcurl request failed [6]: Could not resolve host: gw-xxyyzz
strongswan  | 14[IKE] processing INTERNAL_IP4_DNS attribute
strongswan  | 14[IKE] installing DNS server x.y.z.5 via resolvconf
strongswan  | 14[IKE] processing INTERNAL_IP4_DNS attribute
strongswan  | 14[IKE] installing DNS server x.y.z.195 via resolvconf
strongswan  | 14[IKE] processing INTERNAL_IP4_DNS attribute
strongswan  | 14[IKE] installing DNS server x.y.z.2 via resolvconf
strongswan  | 14[CHD] updown: # resolv.conf from lo.inet.ipsec.x.y.z.195
strongswan  | 14[CHD] updown: # resolv.conf from lo.inet.ipsec.x.y.z.5
strongswan  | 14[CHD] updown: # resolv.conf from lo.inet.ipsec.x.y.z.2
strongswan  | 13[CHD] updown: # resolv.conf from lo.inet.ipsec.x.y.z.195
strongswan  | 13[CHD] updown: # resolv.conf from lo.inet.ipsec.x.y.z.5
strongswan  | 13[CHD] updown: # resolv.conf from lo.inet.ipsec.x.y.z.2

Just a note - I am running now the updown plugin with dns_handler = no to prevent plugin interaction.

The first three resolv.conf lines are from resolvconf -l run from the updown script during --initiate call, second one is during the --terminate call.

@oldium
Copy link
Author

oldium commented Oct 3, 2022

To avoid confusion - I am also running resolvconf -l after the connection is terminated - separately:

#> docker compose exec -- strongswan resolvconf -l
# resolv.conf from lo.inet.ipsec.x.y.z.195
nameserver x.y.z.195

# resolv.conf from lo.inet.ipsec.x.y.z.5
nameserver x.y.z.5

# resolv.conf from lo.inet.ipsec.x.y.z.2
nameserver x.y.z.2

@oldium
Copy link
Author

oldium commented Oct 3, 2022

The part of solution is to write custom updown scripts to (1) configure DNS for roadwarrior from the fixed VPN (the fixed VPN updown script)

Configure where/how?

I wanted to update the swanctl.conf configuration (the DNS pool for roadwarrior) and simply call swanctl --load-all from the updown script of fixed VPN.

(2) setup routes to fixed VPN when roadwarrior connects (the roadwarrior updown script).

What routes exactly? Why are they not there yet when the "fixed" VPN is established?

I meant update firewall to allow routing from roadwarrior subnet to fixed VPN subnet(s), also masquerade.

Sounds a bit hackish. Might be easier to use dnsmasq or similar as DNS proxy.

Yes, sounds better. With docker compose that would be another running service. I could share a volume mount with the dnsmasq configuration and prepare it from the updown script. Anyway, configuration update would be necessary in both cases, just different service to update.

@tobiasbrunner
Copy link
Member

The first three resolv.conf lines are from resolvconf -l run from the updown script during --initiate call, second one is during the --terminate call.

What exactly did you terminate? Only the CHILD_SA? That won't remove the DNS servers. However, when terminating the IKE_SA, you should see removing DNS server ... via resolvconf log messages and the DNS servers should be gone.

Yes, sounds better. With docker compose that would be another running service. I could share a volume mount with the dnsmasq configuration and prepare it from the updown script. Anyway, configuration update would be necessary in both cases, just different service to update.

The advantage is that if the DNS servers change for some reason, you just need to reload dnsmasq and all connected clients can immediately use the new ones as their DNS server address doesn't change (firewall rules for them also don't have to be changed).

@oldium
Copy link
Author

oldium commented Oct 3, 2022

The first three resolv.conf lines are from resolvconf -l run from the updown script during --initiate call, second one is during the --terminate call.

What exactly did you terminate? Only the CHILD_SA? That won't remove the DNS servers. However, when terminating the IKE_SA, you should see removing DNS server ... via resolvconf log messages and the DNS servers should be gone.

I just use swanctl --initiate fixed_vpn and swanctl --terminate fixed_vpn from the command line. The logs show some IKE_SA activity, so this could be what you are talking about - the IKE_SA is still active.

strongswan  | 02[CFG] vici initiate CHILD_SA 'rohlik_vpn'
strongswan  | 08[MGR] checkout IKE_SA by config
strongswan  | 08[MGR] created IKE_SA (unnamed)[1]
strongswan  | 08[IKE] initiating IKE_SA fixed_vpn[1] to x.y.z.zz
strongswan  | 08[IKE] IKE_SA rohlik_vpn[1] state change: CREATED => CONNECTING
strongswan  | 08[ENC] generating IKE_SA_INIT request 0 [ SA KE No N(NATD_S_IP) N(NATD_D_IP) N(FRAG_SUP) N(HASH_ALG) N(REDIR_SUP) ]
strongswan  | 08[MGR] checkin of IKE_SA successful
strongswan  | 03[ENC] parsed a IKE_SA_INIT response header
strongswan  | 05[MGR] IKE_SA rohlik_vpn[1] successfully checked out
strongswan  | 03[ENC] parsed a IKE_SA_INIT response header
strongswan  | 07[MGR] IKE_SA checkout not successful
strongswan  | 05[ENC] parsed IKE_SA_INIT response 0 [ SA KE No N(NATD_S_IP) N(NATD_S_IP) N(NATD_S_IP) N(NATD_D_IP) CERTREQ ]
strongswan  | 05[IKE] establishing CHILD_SA fixed_vpn{1}
strongswan  | 05[MGR] checkin of IKE_SA successful
strongswan  | 14[MGR] IKE_SA rohlik_vpn[1] successfully checked out
strongswan  | 06[MGR] IKE_SA checkout not successful
strongswan  | 14[IKE] IKE_SA rohlik_vpn[1] established between 172.25.0.2[O=...]...x.y.z.zz[x.y.z.zz]
strongswan  | 14[IKE] IKE_SA rohlik_vpn[1] state change: CONNECTING => ESTABLISHED
strongswan  | 14[IKE] maximum IKE_SA lifetime 30725s
strongswan  | 14[CHD] CHILD_SA rohlik_vpn{1} state change: CREATED => INSTALLING
strongswan  | 14[IKE] CHILD_SA rohlik_vpn{1} established with SPIs xxx_i yyy_o and TS x.y.z.zz/32 === x.y.z.zz/8
strongswan  | 14[CHD] CHILD_SA rohlik_vpn{1} state change: INSTALLING => INSTALLED
strongswan  | 14[MGR] checkin of IKE_SA successful
strongswan  | 14[CFG] vici terminate CHILD_SA 'fixed_vpn'
strongswan  | 07[MGR] IKE_SA rohlik_vpn[1] successfully checked out
strongswan  | 07[IKE] closing CHILD_SA fixed_vpn{1} with SPIs xxx_i (0 bytes) yyy_o (0 bytes) and TS x.y.z.zz/32 === x.y.z.zz/8
strongswan  | 07[IKE] sending DELETE for ESP CHILD_SA with SPI xxx
strongswan  | 07[CHD] CHILD_SA fixed_vpn{1} state change: INSTALLED => DELETING
strongswan  | 07[MGR] checkin of IKE_SA successful
strongswan  | 13[MGR] IKE_SA fixed_vpn[1] successfully checked out
strongswan  | 10[MGR] IKE_SA checkout not successful
strongswan  | 13[IKE] CHILD_SA closed
strongswan  | 13[CHD] CHILD_SA fixed_vpn{1} state change: DELETING => DELETED
strongswan  | 13[CHD] CHILD_SA fixed_vpn{1} state change: DELETED => DESTROYING
strongswan  | 13[MGR] checkin of IKE_SA successful
strongswan  | 08[MGR] IKE_SA fixed_vpn[1] successfully checked out
strongswan  | 08[MGR] checkin of IKE_SA successful
strongswan  | 02[MGR] IKE_SA fixed_vpn[1] successfully checked out
strongswan  | 08[MGR] checkin of IKE_SA successful
strongswan  | 02[MGR] IKE_SA fixed_vpn[1] successfully checked out
...

From time to time there is IKE_SA checkout not successful followed by checkin of IKE_SA successful, so this does not look like an issue.

Yes, sounds better. With docker compose that would be another running service. I could share a volume mount with the dnsmasq configuration and prepare it from the updown script. Anyway, configuration update would be necessary in both cases, just different service to update.

The advantage is that if the DNS servers change for some reason, you just need to reload dnsmasq and all connected clients can immediately use the new ones as their DNS server address doesn't change (firewall rules for them also don't have to be changed).

Great point, thanks. I will do that.

Thanks for hints, I think I have now a sufficiently working setup to continue. When I have time I will have a look at the /etc/resolv.conf read/write issue inside Docker - I will add some logging around the fread call to check at least any error code.

Also please have a look at patch oldium@23a830e, which fixes some compilation issues under alpine:edge Docker image - two implicit declarations fixed by including string.h and one unused function print_sourceline.

@tobiasbrunner
Copy link
Member

I just use swanctl --initiate fixed_vpn and swanctl --terminate fixed_vpn from the command line.

Are you sure you didn't also specify --child or -c for both? The commands should fail if none of the --ike*/--child* options are passed. Because you are really only terminating the CHILD_SA:

strongswan  | 14[CFG] vici terminate CHILD_SA 'fixed_vpn'

To terminate the IKE_SA, you have to pass --ike/-i to --terminate instead.

Also please have a look at patch oldium@23a830e, which fixes some compilation issues under alpine:edge Docker image - two implicit declarations fixed by including string.h and one unused function print_sourceline.

Thanks, pushed them to the compile-fixes branch. Will merge them to master after the release today.

@oldium
Copy link
Author

oldium commented Oct 3, 2022

I just use swanctl --initiate fixed_vpn and swanctl --terminate fixed_vpn from the command line.

Are you sure you didn't also specify --child or -c for both? The commands should fail if none of the --ike*/--child* options are passed. Because you are really only terminating the CHILD_SA:

strongswan  | 14[CFG] vici terminate CHILD_SA 'fixed_vpn'

To terminate the IKE_SA, you have to pass --ike/-i to --terminate instead.

Sorry, my bad, I am really using swanctl --initiate --child fixed_vpn, same with swanctl --terminate --child fixed_vpn. When I do swanctl --terminate --ike fixed_vpn, then the DNS servers really vanish - resolvconf -l is empty. I am really a novice in this area.

Also please have a look at patch oldium@23a830e, which fixes some compilation issues under alpine:edge Docker image - two implicit declarations fixed by including string.h and one unused function print_sourceline.

Thanks, pushed them to the compile-fixes branch. Will merge them to master after the release today.

Thanks :-)

@tobiasbrunner
Copy link
Member

and one unused function print_sourceline.

By the way, didn't you run into the issue that esc() was unused after removing print_sourceline()? (I've added an ifdef there too, see the branch.)

@oldium
Copy link
Author

oldium commented Oct 3, 2022

and one unused function print_sourceline.

By the way, didn't you run into the issue that esc() was unused after removing print_sourceline()? (I've added an ifdef there too, see the branch.)

No, but I am not compiling everything, so I might have missed that one (I used https://github.com/Stanback/alpine-strongswan-vpn Dockerfile as a starting point, now compiling from Git master):

 ./configure --prefix=/usr --sysconfdir=/etc --libexecdir=/usr/lib --with-ipsecdir=/usr/lib/strongswan --enable-acert --enable-addrblock --enable-aesni --enable-blowfish --enable-chapoly --enable-certexpire --enable-cmd --enable-conftest --enable-counters --enable-coupling --enable-curl --enable-dhcp --enable-dnscert --enable-duplicheck --enable-eap-dynamic --enable-eap-identity --enable-eap-md5 --enable-eap-mschapv2 --enable-eap-peap --enable-eap-radius --enable-eap-tls --enable-eap-tnc --enable-eap-ttls --enable-error-notify --enable-farp --enable-files --enable-forecast --enable-gcm --enable-md4 --enable-ipseckey --enable-lookip --enable-mediation --enable-newhope --enable-ntru --enable-openssl --enable-resolve --enable-sha3 --enable-whitelist --disable-aes --disable-des --disable-gmp --disable-hmac --disable-ikev1 --disable-md5 --disable-rc2 --disable-sha1 --disable-sha2 --enable-shared --disable-static

@oldium
Copy link
Author

oldium commented Oct 3, 2022

Also please have a look at patch oldium@23a830e, which fixes some compilation issues under alpine:edge Docker image - two implicit declarations fixed by including string.h and one unused function print_sourceline.

Thanks, pushed them to the compile-fixes branch. Will merge them to master after the release today.

Branch compile-fixes builds fine for me. 👍

@tobiasbrunner
Copy link
Member

No, but I am not compiling everything, so I might miss that one:

It's an internal function in backtrace.c so it doesn't depend on these features (the only option that could affect it would be --enable-unwind-backtraces as that would enable print_sourceline() if backtrace() isn't supported). I guess GCC doesn't complain about unused static inline functions (at least in some versions), while clang does.

Branch compile-fixes builds fine for me. +1

Thanks for testing.

@oldium
Copy link
Author

oldium commented Oct 4, 2022

Regarding the behaviour of the resolve plugin - I added some logging (https://github.com/oldium/strongswan) and discovered that the unlink operation is actually failing, not the reading:

strongswan | 08[IKE] deleting file /etc/resolv.conf failed: Resource busy
strongswan | 08[IKE] installing DNS server x.y.z.5 to /etc/resolv.conf
strongswan | 08[IKE] deleting file /etc/resolv.conf failed: Resource busy
strongswan | 08[IKE] installing DNS server x.y.z.195 to /etc/resolv.conf
strongswan | 08[IKE] deleting file /etc/resolv.conf failed: Resource busy
strongswan | 08[IKE] installing DNS server x.y.z.2 to /etc/resolv.conf

@oldium
Copy link
Author

oldium commented Oct 4, 2022

It looks like this is Docker specific, you cannot delete /etc/resolv.conf, so changing the target file (option charon.plugins.resolve.file) solves the issue - https://stackoverflow.com/a/60576223.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants