# PPPoE WAN session. ISP credentials are entered once at `clan vars generate` # (prompts). Both are secret — AIS often uses the same string for username and # password — so neither may land in the Nix store: pppd reads the username from # an included secret options file and the password from chap/pap-secrets. { config, lib, ... }: let cfg = config.cnx.router; creds = config.clan.core.vars.generators.pppoe-credentials; in { config = lib.mkIf cfg.enable { clan.core.vars.generators.pppoe-credentials = { prompts.username = { description = "PPPoE username (from the ISP)"; type = "hidden"; }; prompts.password = { description = "PPPoE password (from the ISP)"; type = "hidden"; }; files."user-opts".secret = true; files."chap-secrets".secret = true; script = '' user="$(cat "$prompts"/username)" pass="$(cat "$prompts"/password)" printf 'user "%s"\n' "$user" > "$out"/user-opts printf '"%s" * "%s"\n' "$user" "$pass" > "$out"/chap-secrets ''; }; services.pppd = { enable = true; peers.wan = { autostart = true; config = '' plugin pppoe.so ${cfg.wan.pppInterface} ifname ppp0 file ${creds.files."user-opts".path} noipdefault defaultroute noauth hide-password persist maxfail 0 holdoff 5 lcp-echo-interval 15 lcp-echo-failure 3 +ipv6 mtu 1492 mru 1492 ''; }; }; # pppd looks up the password for `user` in these files at dial time; both # point at the same generated `"" * ""` line (PAP and CHAP). environment.etc."ppp/chap-secrets".source = creds.files."chap-secrets".path; environment.etc."ppp/pap-secrets".source = creds.files."chap-secrets".path; }; }