9 L
.resolveDefault(fs
.stat('/usr/sbin/nginx'), {}),
10 L
.resolveDefault(fs
.stat('/usr/sbin/uhttpd'), {})
14 render: function (stats
) {
17 m
= new form
.Map("acme", _("ACME certificates"),
18 _("This configures ACME (Letsencrypt) automatic certificate installation. " +
19 "Simply fill out this to have the router configured with Letsencrypt-issued " +
20 "certificates for the web interface. " +
21 "Note that the domain names in the certificate must already be configured to " +
22 "point at the router's public IP address. " +
23 "Once configured, issuing certificates can take a while. " +
24 "Check the logs for progress and any errors."));
26 s
= m
.section(form
.TypedSection
, "acme", _("ACME global config"));
29 o
= s
.option(form
.Value
, "state_dir", _("State directory"),
30 _("Where certs and other state files are kept."));
32 o
.datatype
= "directory";
34 o
= s
.option(form
.Value
, "account_email", _("Account email"),
35 _("Email address to associate with account key."))
37 o
.datatype
= "minlength(1)";
39 o
= s
.option(form
.Flag
, "debug", _("Enable debug logging"));
42 s
= m
.section(form
.GridSection
, "cert", _("Certificate config"))
45 s
.nodescriptions
= true;
47 o
= s
.tab("general", _("General Settings"));
48 o
= s
.tab("challenge", _("Challenge Validation"));
49 o
= s
.tab("advanced", _('Advanced Settings'));
51 o
= s
.taboption('general', form
.Flag
, "enabled", _("Enabled"));
54 o
= s
.taboption('general', form
.Flag
, "use_staging", _("Use staging server"),
55 _("Get certificate from the Letsencrypt staging server " +
56 "(use for testing; the certificate won't be valid)."));
60 o
= s
.taboption('general', form
.ListValue
, "keylength", _("Key size"),
61 _("Key size (and type) for the generated certificate."));
62 o
.value("2048", _("RSA 2048 bits"));
63 o
.value("3072", _("RSA 3072 bits"));
64 o
.value("4096", _("RSA 4096 bits"));
65 o
.value("ec-256", _("ECC 256 bits"));
66 o
.value("ec-384", _("ECC 384 bits"));
70 o
= s
.taboption('general', form
.DynamicList
, "domains", _("Domain names"),
71 _("Domain names to include in the certificate. " +
72 "The first name will be the subject name, subsequent names will be alt names. " +
73 "Note that all domain names must point at the router in the global DNS."));
74 o
.datatype
= "list(string)";
76 if (stats
[1].type
=== 'file') {
77 o
= s
.taboption('general', form
.Flag
, "update_uhttpd", _("Use for uhttpd"),
78 _("Update the uhttpd config with this certificate once issued " +
79 "(only select this for one certificate). " +
80 "Is also available luci-app-uhttpd to configure uhttpd form the LuCI interface."));
85 if (stats
[0].type
=== 'file') {
86 o
= s
.taboption('general', form
.Flag
, "update_nginx", _("Use for nginx"),
87 _("Update the nginx config with this certificate once issued " +
88 "(only select this for one certificate). " +
89 "Nginx must support ssl, if not it won't start as it needs to be " +
90 "compiled with ssl support to use cert options"));
95 o
= s
.taboption('challenge', form
.ListValue
, "validation_method", _("Validation method"),
96 _("Standalone mode will use the built-in webserver of acme.sh to issue a certificate. " +
97 "Webroot mode will use an existing webserver to issue a certificate. " +
98 "DNS mode will allow you to use the DNS API of your DNS provider to issue a certificate."));
99 o
.value("standalone", _("Standalone"));
100 o
.value("webroot", _("Webroot"));
101 o
.value("dns", _("DNS"));
102 o
.default = "standalone";
104 o
= s
.taboption('challenge', form
.Value
, "webroot", _("Webroot directory"),
105 _("Webserver root directory. Set this to the webserver " +
106 "document root to run Acme in webroot mode. The web " +
107 "server must be accessible from the internet on port 80."));
109 o
.depends("validation_method", "webroot");
112 o
= s
.taboption('challenge', form
.Value
, "dns", _("DNS API"),
113 _("To use DNS mode to issue certificates, set this to the name of a DNS API supported by acme.sh. " +
114 "See https://github.com/acmesh-official/acme.sh/wiki/dnsapi for the list of available APIs. " +
115 "In DNS mode, the domain name does not have to resolve to the router IP. " +
116 "DNS mode is also the only mode that supports wildcard certificates. " +
117 "Using this mode requires the acme-dnsapi package to be installed."));
118 o
.depends("validation_method", "dns");
121 o
= s
.taboption('challenge', form
.DynamicList
, "credentials", _("DNS API credentials"),
122 _("The credentials for the DNS API mode selected above. " +
123 "See https://github.com/acmesh-official/acme.sh/wiki/dnsapi for the format of credentials required by each API. " +
124 "Add multiple entries here in KEY=VAL shell variable format to supply multiple credential variables."))
125 o
.datatype
= "list(string)";
126 o
.depends("validation_method", "dns");
129 o
= s
.taboption('challenge', form
.Value
, "calias", _("Challenge Alias"),
130 _("The challenge alias to use for ALL domains. " +
131 "See https://github.com/acmesh-official/acme.sh/wiki/DNS-alias-mode for the details of this process. " +
132 "LUCI only supports one challenge alias per certificate."));
133 o
.depends("validation_method", "dns");
136 o
= s
.taboption('challenge', form
.Value
, "dalias", _("Domain Alias"),
137 _("The domain alias to use for ALL domains. " +
138 "See https://github.com/acmesh-official/acme.sh/wiki/DNS-alias-mode for the details of this process. " +
139 "LUCI only supports one challenge domain per certificate."));
140 o
.depends("validation_method", "dns");
143 o
= s
.taboption('advanced', form
.Flag
, "use_acme_server",
144 _("Custom ACME CA"), _("Use a custom CA instead of Let's Encrypt."));
145 o
.depends("use_staging", "0");
149 o
= s
.taboption('advanced', form
.Value
, "acme_server", _("ACME server URL"),
150 _("Custom ACME server directory URL."));
151 o
.depends("use_acme_server", "1");
152 o
.placeholder
= "https://api.buypass.com/acme/directory";
156 o
= s
.taboption('advanced', form
.Value
, 'days', _('Days until renewal'));
159 o
.datatype
= 'uinteger';