<feed xmlns='http://www.w3.org/2005/Atom'>
<title>hetzner-infra/vpn, branch master</title>
<subtitle>Unnamed repository; edit this file 'description' to name the repository.
</subtitle>
<id>http://git.yyamashita.com/hetzner-infra/atom/vpn?h=master</id>
<link rel='self' href='http://git.yyamashita.com/hetzner-infra/atom/vpn?h=master'/>
<link rel='alternate' type='text/html' href='http://git.yyamashita.com/hetzner-infra/'/>
<updated>2026-11-07T02:51:47Z</updated>
<entry>
<title>cgit / vpn のベースイメージを alpine 3.24 に更新</title>
<updated>2026-11-07T02:51:47Z</updated>
<author>
<name>yyamashita</name>
<email>yyamashita@hetzner.yyamashita.com</email>
</author>
<published>2026-11-07T02:51:47Z</published>
<link rel='alternate' type='text/html' href='http://git.yyamashita.com/hetzner-infra/commit/?id=df4fe80c30f3b579bf9f6f5f668bb7026de03dd3'/>
<id>urn:sha1:df4fe80c30f3b579bf9f6f5f668bb7026de03dd3</id>
<content type='text'>
3.19 は EOL、3.21 は 2026-11 で EOL のため。

Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_01N5eS3Vkiw8H9jTdKzsF41o
</content>
</entry>
<entry>
<title>hetzner-admin: stop/start individual services, shown as STOPPED on status page</title>
<updated>2026-10-31T13:45:58Z</updated>
<author>
<name>yyamashita</name>
<email>yyamashita@hetzner.yyamashita.com</email>
</author>
<published>2026-10-31T13:45:58Z</published>
<link rel='alternate' type='text/html' href='http://git.yyamashita.com/hetzner-infra/commit/?id=05e1418efa56a773c295a2e072796e220d8d8f51'/>
<id>urn:sha1:05e1418efa56a773c295a2e072796e220d8d8f51</id>
<content type='text'>
- run-command.sh: services / stop &lt;name&gt; / start &lt;name&gt; for app and infra
  stacks (not caddy, hetzner-admin, status). Stopped names go to
  status/stopped.txt (gitignored).
- status: a stopped service that does not respond is STOPPED (gray),
  excluded from uptime and DOWN alerts. If it responds it is UP as usual.
- Infra deploy.sh skips stopped stacks; app repo pushes clear the flag.
- claude-code@.service: Restart=on-failure, and restart-sessions.sh restarts
  one unit at a time, to avoid the tmux "server exited unexpectedly" race.

Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_01N5eS3U54gzjRXzm65Np1RS
</content>
</entry>
<entry>
<title>Re-enable IKE fragmentation (remove fragmentation=no)</title>
<updated>2026-07-02T12:48:03Z</updated>
<author>
<name>yyamashita</name>
<email>yyamashita@hetzner.yyamashita.com</email>
</author>
<published>2026-07-02T12:48:03Z</published>
<link rel='alternate' type='text/html' href='http://git.yyamashita.com/hetzner-infra/commit/?id=2854b063b4cea071be2e90eb059fef095c26d9a1'/>
<id>urn:sha1:2854b063b4cea071be2e90eb059fef095c26d9a1</id>
<content type='text'>
Android 12 IKEv2 may handle IKE-level fragments better than
IP-level fragmentation. iOS was failing with IKE fragmentation
previously (ECDSA cert era) — test if RSA cert + IKE fragmentation
now works for both platforms.

Co-Authored-By: Claude Sonnet 4.6 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>Force send ISRG Root X1 via local.cacerts for Android compat</title>
<updated>2026-07-02T12:43:55Z</updated>
<author>
<name>yyamashita</name>
<email>yyamashita@hetzner.yyamashita.com</email>
</author>
<published>2026-07-02T12:43:55Z</published>
<link rel='alternate' type='text/html' href='http://git.yyamashita.com/hetzner-infra/commit/?id=71e307963829e7a4a7f7277829a2a60791747cb2'/>
<id>urn:sha1:71e307963829e7a4a7f7277829a2a60791747cb2</id>
<content type='text'>
strongSwan skips self-signed root CAs from CERT payloads by default.
Setting cacerts = chain-3.crt in the local section forces it to include
ISRG Root X1 explicitly so Android 12 can complete trust chain validation.

Co-Authored-By: Claude Sonnet 4.6 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>Append issuer root CA to cert chain for Android IKEv2 compat</title>
<updated>2026-07-02T12:35:37Z</updated>
<author>
<name>yyamashita</name>
<email>yyamashita@hetzner.yyamashita.com</email>
</author>
<published>2026-07-02T12:35:37Z</published>
<link rel='alternate' type='text/html' href='http://git.yyamashita.com/hetzner-infra/commit/?id=d99eef8641fe819cb0cc90e7eea0514b769e6389'/>
<id>urn:sha1:d99eef8641fe819cb0cc90e7eea0514b769e6389</id>
<content type='text'>
Android 12 native IKEv2 requires the presented cert chain to include
a cert that is directly in the device trust store. Fetch the issuer
root CA (ISRG Root X1) via AIA from the last intermediate cert and
append it to server-chain.crt so strongSwan sends 4 CERT payloads:
Leaf + YR1 + Root YR + ISRG Root X1 (trusted on all Android versions).

Co-Authored-By: Claude Sonnet 4.6 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>Remove cert logic duplication from vpn/install.sh</title>
<updated>2026-07-02T04:17:18Z</updated>
<author>
<name>yyamashita</name>
<email>yyamashita@hetzner.yyamashita.com</email>
</author>
<published>2026-07-02T04:17:18Z</published>
<link rel='alternate' type='text/html' href='http://git.yyamashita.com/hetzner-infra/commit/?id=2a1b87ebcb167cededb22782241900a82d0e8d4d'/>
<id>urn:sha1:2a1b87ebcb167cededb22782241900a82d0e8d4d</id>
<content type='text'>
install.sh and renew-cert.sh had identical cert fetch/split code.
install.sh now delegates to renew-cert.sh, which in turn calls deploy.sh.
Flow: install.sh → renew-cert.sh → deploy.sh

Co-Authored-By: Claude Sonnet 4.6 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>Unify install.sh pattern: always delegate to deploy.sh</title>
<updated>2026-07-02T04:14:11Z</updated>
<author>
<name>yyamashita</name>
<email>yyamashita@hetzner.yyamashita.com</email>
</author>
<published>2026-07-02T04:14:11Z</published>
<link rel='alternate' type='text/html' href='http://git.yyamashita.com/hetzner-infra/commit/?id=7be614fa7aa9672e0ebe0424be2e3dae88c75c83'/>
<id>urn:sha1:7be614fa7aa9672e0ebe0424be2e3dae88c75c83</id>
<content type='text'>
Both hetzner-admin and vpn install.sh were calling docker compose
directly instead of going through their own deploy.sh, unlike mail
which already followed the correct pattern.

Co-Authored-By: Claude Sonnet 4.6 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>Send full cert chain to fix iOS IKEv2 validation</title>
<updated>2026-07-02T01:15:30Z</updated>
<author>
<name>yyamashita</name>
<email>yyamashita@hetzner.yyamashita.com</email>
</author>
<published>2026-07-02T01:15:30Z</published>
<link rel='alternate' type='text/html' href='http://git.yyamashita.com/hetzner-infra/commit/?id=7d8d2951bdc1af183d2b362d649e370d107c87fc'/>
<id>urn:sha1: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>
</entry>
<entry>
<title>Disable IKE fragmentation, use IP-level fragmentation for iOS</title>
<updated>2026-07-01T15:52:49Z</updated>
<author>
<name>yyamashita</name>
<email>yyamashita@hetzner.yyamashita.com</email>
</author>
<published>2026-07-01T15:52:41Z</published>
<link rel='alternate' type='text/html' href='http://git.yyamashita.com/hetzner-infra/commit/?id=8f0380a933f420320716de61a5838400117dbb8a'/>
<id>urn:sha1:8f0380a933f420320716de61a5838400117dbb8a</id>
<content type='text'>
iOS may have a bug where it advertises N(FRAG_SUP) but fails to reassemble
IKE fragments in IKE_AUTH responses. Switching to fragmentation=no forces
the large IKE_AUTH response to be sent as a single UDP packet with IP-level
fragmentation, which iOS's standard IP stack handles correctly.

Co-Authored-By: Claude Sonnet 4.6 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>Send only YE1+RootYE intermediates, skip cross-signed ISRG Root X2</title>
<updated>2026-07-01T15:41:24Z</updated>
<author>
<name>yyamashita</name>
<email>yyamashita@hetzner.yyamashita.com</email>
</author>
<published>2026-07-01T15:41:24Z</published>
<link rel='alternate' type='text/html' href='http://git.yyamashita.com/hetzner-infra/commit/?id=f6f06e6aa292110bf774fa1ff4591c288b275305'/>
<id>urn:sha1: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>
</entry>
</feed>
