<feed xmlns='http://www.w3.org/2005/Atom'>
<title>hetzner-infra/vpn/entrypoint.sh, branch master</title>
<subtitle>Unnamed repository; edit this file 'description' to name the repository.
</subtitle>
<link rel='alternate' type='text/html' href='http://git.yyamashita.com/hetzner-infra/'/>
<entry>
<title>Send full cert chain to fix iOS IKEv2 validation</title>
<updated>2026-07-02T01:15:30+00:00</updated>
<author>
<name>yyamashita</name>
<email>yyamashita@hetzner.yyamashita.com</email>
</author>
<published>2026-07-02T01:15:30+00:00</published>
<link rel='alternate' type='text/html' href='http://git.yyamashita.com/hetzner-infra/commit/?id=7d8d2951bdc1af183d2b362d649e370d107c87fc'/>
<id>7d8d2951bdc1af183d2b362d649e370d107c87fc</id>
<content type='text'>
iOS IKEv2 does not look up intermediates from the system trust store
(unlike TLS/HTTPS). Send all 3 certs: YE1 + Root YE + cross-signed
ISRG Root X2, so iOS can build the full chain through to ISRG Root X1.

Co-Authored-By: Claude Sonnet 4.6 &lt;noreply@anthropic.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
iOS IKEv2 does not look up intermediates from the system trust store
(unlike TLS/HTTPS). Send all 3 certs: YE1 + Root YE + cross-signed
ISRG Root X2, so iOS can build the full chain through to ISRG Root X1.

Co-Authored-By: Claude Sonnet 4.6 &lt;noreply@anthropic.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Send only YE1+RootYE intermediates, skip cross-signed ISRG Root X2</title>
<updated>2026-07-01T15:41:24+00:00</updated>
<author>
<name>yyamashita</name>
<email>yyamashita@hetzner.yyamashita.com</email>
</author>
<published>2026-07-01T15:41:24+00:00</published>
<link rel='alternate' type='text/html' href='http://git.yyamashita.com/hetzner-infra/commit/?id=f6f06e6aa292110bf774fa1ff4591c288b275305'/>
<id>f6f06e6aa292110bf774fa1ff4591c288b275305</id>
<content type='text'>
iOS 14+ and Android 11+ have ISRG Root X2 in their trust store.
Sending the cross-signed ISRG Root X2 alongside the trusted
self-signed version can confuse the cert path-building algorithm.

Chain: leaf -&gt; YE1 -&gt; Root YE -&gt; [ISRG Root X2 from trust store]

Co-Authored-By: Claude Sonnet 4.6 &lt;noreply@anthropic.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
iOS 14+ and Android 11+ have ISRG Root X2 in their trust store.
Sending the cross-signed ISRG Root X2 alongside the trusted
self-signed version can confuse the cert path-building algorithm.

Chain: leaf -&gt; YE1 -&gt; Root YE -&gt; [ISRG Root X2 from trust store]

Co-Authored-By: Claude Sonnet 4.6 &lt;noreply@anthropic.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Fix VPN cert chain: split multi-cert PEM for strongSwan</title>
<updated>2026-07-01T15:28:31+00:00</updated>
<author>
<name>yyamashita</name>
<email>yyamashita@hetzner.yyamashita.com</email>
</author>
<published>2026-07-01T15:28:31+00:00</published>
<link rel='alternate' type='text/html' href='http://git.yyamashita.com/hetzner-infra/commit/?id=c463eddaab816b6ffe032f37f4228e4b22a1425d'/>
<id>c463eddaab816b6ffe032f37f4228e4b22a1425d</id>
<content type='text'>
Caddy's cert chain contains 4 certs:
  1. leaf (signed by YE1)
  2. YE1 (signed by Root YE)
  3. Root YE (cross-signed by ISRG Root X2)
  4. ISRG Root X2 (cross-signed by ISRG Root X1)

iOS/Android trust ISRG Root X1 but not Root YE directly.
The full cross-signed chain must be sent in IKE_AUTH.

strongSwan only reads the first cert from a multi-cert PEM file,
so entrypoint.sh now splits server-chain.crt into individual files
in x509ca/ before starting charon.

Co-Authored-By: Claude Sonnet 4.6 &lt;noreply@anthropic.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Caddy's cert chain contains 4 certs:
  1. leaf (signed by YE1)
  2. YE1 (signed by Root YE)
  3. Root YE (cross-signed by ISRG Root X2)
  4. ISRG Root X2 (cross-signed by ISRG Root X1)

iOS/Android trust ISRG Root X1 but not Root YE directly.
The full cross-signed chain must be sent in IKE_AUTH.

strongSwan only reads the first cert from a multi-cert PEM file,
so entrypoint.sh now splits server-chain.crt into individual files
in x509ca/ before starting charon.

Co-Authored-By: Claude Sonnet 4.6 &lt;noreply@anthropic.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Fix VPN: send certificate always, split cert chain, fix entrypoint</title>
<updated>2026-07-01T01:16:13+00:00</updated>
<author>
<name>yyamashita</name>
<email>yyamashita@hetzner.yyamashita.com</email>
</author>
<published>2026-07-01T01:16:13+00:00</published>
<link rel='alternate' type='text/html' href='http://git.yyamashita.com/hetzner-infra/commit/?id=11b6518b75e06dcd716bf04e133ef1a67c591cae'/>
<id>11b6518b75e06dcd716bf04e133ef1a67c591cae</id>
<content type='text'>
- swanctl.conf.tpl: send_cert = always (fix Android cert verification failure)
- docker-compose.yml: mount intermediate CAs to /etc/swanctl/x509ca/
- install.sh: split server.crt into leaf + chain for proper chain distribution
- entrypoint.sh: run charon directly for Docker log visibility,
  fix sysctl error handling, fix charon binary path
- strongswan.conf: increase IKE log level to 4 for debugging

Co-Authored-By: Claude Sonnet 4.6 &lt;noreply@anthropic.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
- swanctl.conf.tpl: send_cert = always (fix Android cert verification failure)
- docker-compose.yml: mount intermediate CAs to /etc/swanctl/x509ca/
- install.sh: split server.crt into leaf + chain for proper chain distribution
- entrypoint.sh: run charon directly for Docker log visibility,
  fix sysctl error handling, fix charon binary path
- strongswan.conf: increase IKE log level to 4 for debugging

Co-Authored-By: Claude Sonnet 4.6 &lt;noreply@anthropic.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Fix VPN entrypoint: handle sysctl read-only in host network mode</title>
<updated>2026-06-30T13:33:23+00:00</updated>
<author>
<name>yyamashita</name>
<email>yyamashita@hetzner.yyamashita.com</email>
</author>
<published>2026-06-30T13:33:23+00:00</published>
<link rel='alternate' type='text/html' href='http://git.yyamashita.com/hetzner-infra/commit/?id=dd15de090cc70454f5039f8a1a9bb1d98358435b'/>
<id>dd15de090cc70454f5039f8a1a9bb1d98358435b</id>
<content type='text'>
network_mode: host では /proc/sys への書き込みが制限されるため、
sysctl の失敗を無視してホスト側の設定値を確認するよう変更。

Co-Authored-By: Claude Sonnet 4.6 &lt;noreply@anthropic.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
network_mode: host では /proc/sys への書き込みが制限されるため、
sysctl の失敗を無視してホスト側の設定値を確認するよう変更。

Co-Authored-By: Claude Sonnet 4.6 &lt;noreply@anthropic.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Add strongSwan IKEv2 VPN service</title>
<updated>2026-06-30T13:29:07+00:00</updated>
<author>
<name>yyamashita</name>
<email>yyamashita@hetzner.yyamashita.com</email>
</author>
<published>2026-06-30T13:29:07+00:00</published>
<link rel='alternate' type='text/html' href='http://git.yyamashita.com/hetzner-infra/commit/?id=58f7917662ff92a3712289acccff8310c8f1baff'/>
<id>58f7917662ff92a3712289acccff8310c8f1baff</id>
<content type='text'>
- vpn/: Dockerfile, docker-compose.yml, swanctl.conf.tpl, entrypoint.sh
- install.sh: Caddy 証明書流用 + コンテナ起動
- renew-cert.sh: 証明書更新 + swanctl ホットリロード
- caddy/Caddyfile: vpn.yyamashita.com 追加（Let's Encrypt 証明書取得用）
- post-receive: vpn/deploy.sh を追加
- setup-route53.py: WEB_SUBDOMAINS に vpn を追加

Co-Authored-By: Claude Sonnet 4.6 &lt;noreply@anthropic.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
- vpn/: Dockerfile, docker-compose.yml, swanctl.conf.tpl, entrypoint.sh
- install.sh: Caddy 証明書流用 + コンテナ起動
- renew-cert.sh: 証明書更新 + swanctl ホットリロード
- caddy/Caddyfile: vpn.yyamashita.com 追加（Let's Encrypt 証明書取得用）
- post-receive: vpn/deploy.sh を追加
- setup-route53.py: WEB_SUBDOMAINS に vpn を追加

Co-Authored-By: Claude Sonnet 4.6 &lt;noreply@anthropic.com&gt;
</pre>
</div>
</content>
</entry>
</feed>
