mirror of
https://github.com/outbackdingo/labca.git
synced 2026-01-27 18:19:33 +00:00
Merge branch 'release/21.09'
* release/21.09: Bump boulder version to release-2021-08-31 Move patch files to subdir for cleaner main dir Add some troubleshooting info on CAA (#23) Make initial setup phase more robust Make initial setup phase more robust Show more information on page to diagnose initial problems Suppress checksum warning on "message repeated X times" lines Show more information on page to diagnose initial problems
This commit is contained in:
@@ -105,6 +105,12 @@ Some log files to check in case of issues are:
|
||||
|
||||
If you get "No valid IP addresses found for <hostname>" in /etc/nginx/ssl/acme_tiny.log, solve it by entering the hostname in your local DNS. Same for "Could not resolve host: <hostname>" in /var/log/labca.err.
|
||||
|
||||
When issuing a certificate, LabCA/boulder checks for CAA (Certification Authority Authorization) records in DNS, which specify what CAs are allowed to issue certificates for the domain. If you get an error like "SERVFAIL looking up CAA for internal" or "CAA record for ca01.foo.internal prevents issuance", you can try to add something like this to your DNS domain:
|
||||
```
|
||||
foo.internal. CAA 0 issue "foo.internal"
|
||||
```
|
||||
See also the [Let's Encrypt™ page on CAA](https://letsencrypt.org/docs/caa/).
|
||||
|
||||
### NOTE
|
||||
|
||||
Although LabCA tries to be as robust as possible, use it at your own risk. If you depend on it, make sure that you know what you are doing!
|
||||
|
||||
33
commander
33
commander
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
set -euo pipefail
|
||||
|
||||
LOGFILE=/home/labca/logs/commander.log
|
||||
|
||||
@@ -18,8 +18,15 @@ function wait_server() {
|
||||
|
||||
local status=0
|
||||
local cnt=0
|
||||
|
||||
set +e
|
||||
res=$(curl -o /dev/null -sSLk --head --write-out '%{http_code}\n' $url 2>&1)
|
||||
if [ $? -ne 0 ]; then
|
||||
echo -n $res
|
||||
fi
|
||||
set -e
|
||||
while [ $cnt -lt 40 ] && [ "$status" != "200" ]; do
|
||||
status=$(curl -o /dev/null -sSL --head --write-out '%{http_code}\n' $url)
|
||||
status=$(curl -o /dev/null -sSL --head --write-out '%{http_code}\n' $url 2>>$LOGFILE)
|
||||
let cnt=$cnt+1
|
||||
if [ "$status" != "200" ]; then
|
||||
sleep 5
|
||||
@@ -70,17 +77,25 @@ case $txt in
|
||||
service nginx restart
|
||||
;;
|
||||
"log-cert")
|
||||
tail -200 /etc/nginx/ssl/acme_tiny.log
|
||||
[ -f /etc/nginx/ssl/acme_tiny.log ] && tail -200 /etc/nginx/ssl/acme_tiny.log || /bin/true
|
||||
exit 0
|
||||
;;
|
||||
"log-commander")
|
||||
[ -f $LOGFILE ] && tail -200 $LOGFILE || /bin/true
|
||||
exit 0
|
||||
;;
|
||||
"log-boulder")
|
||||
cd /home/labca/boulder
|
||||
docker-compose logs -f --no-color --tail=50 boulder
|
||||
;;
|
||||
"log-boulder-notail")
|
||||
cd /home/labca/boulder
|
||||
docker-compose logs --no-color --tail=50 boulder
|
||||
;;
|
||||
"log-audit")
|
||||
cd /home/labca/boulder
|
||||
docker-compose logs --no-color boulder | grep "\[AUDIT\]" | grep -v "grpc: parseServiceConfig error unmarshaling due to unexpected end of JSON input" | tail -50
|
||||
docker-compose logs -f --no-color --tail=0 boulder
|
||||
docker-compose logs -f --no-color --tail=0 boulder | grep "\[AUDIT\]"
|
||||
;;
|
||||
"log-activity")
|
||||
cd /home/labca/boulder
|
||||
@@ -92,11 +107,19 @@ case $txt in
|
||||
cd /home/labca/boulder
|
||||
docker-compose logs -f --no-color --tail=50 labca
|
||||
;;
|
||||
"log-labca-notail")
|
||||
cd /home/labca/boulder
|
||||
docker-compose logs --no-color --tail=50 labca
|
||||
;;
|
||||
"log-labca-err")
|
||||
[ -f /var/log/labca.err ] && tail -200 /var/log/labca.err || /bin/true
|
||||
exit 0
|
||||
;;
|
||||
"log-web")
|
||||
tail -f -n 50 /var/log/nginx/access.log
|
||||
;;
|
||||
"log-weberr")
|
||||
tail -200 /var/log/nginx/error.log
|
||||
[ -f /var/log/nginx/error.log ] && tail -200 /var/log/nginx/error.log || /bin/true
|
||||
exit 0
|
||||
;;
|
||||
"log-components")
|
||||
|
||||
@@ -47,6 +47,9 @@ func _parseLine(line string, loc *time.Location) Activity {
|
||||
|
||||
re := regexp.MustCompile("^.*\\|\\s*(\\S)(\\S+) (\\S+) (\\S+) (.*)$")
|
||||
result := re.FindStringSubmatch(line)
|
||||
if len(result) == 0 {
|
||||
return activity
|
||||
}
|
||||
|
||||
activity.Class = ""
|
||||
if result[1] == "W" {
|
||||
|
||||
130
gui/main.go
130
gui/main.go
@@ -186,10 +186,18 @@ func (cfg *SetupConfig) Validate(orgRequired bool) bool {
|
||||
cfg.Errors["LockdownDomains"] = "Please enter one or more domains that this PKI host is locked down to"
|
||||
}
|
||||
|
||||
if cfg.DomainMode == "lockdown" && strings.HasPrefix(cfg.LockdownDomains, ".") {
|
||||
cfg.Errors["LockdownDomains"] = "Domain should not start with a dot"
|
||||
}
|
||||
|
||||
if cfg.DomainMode == "whitelist" && strings.TrimSpace(cfg.WhitelistDomains) == "" {
|
||||
cfg.Errors["WhitelistDomains"] = "Please enter one or more domains that are whitelisted for this PKI host"
|
||||
}
|
||||
|
||||
if cfg.DomainMode == "whitelist" && strings.HasPrefix(cfg.WhitelistDomains, ".") {
|
||||
cfg.Errors["WhitelistDomains"] = "Domain should not start with a dot"
|
||||
}
|
||||
|
||||
return len(cfg.Errors) == 0
|
||||
}
|
||||
|
||||
@@ -210,7 +218,7 @@ func getSession(w http.ResponseWriter, r *http.Request) *sessions.Session {
|
||||
}
|
||||
|
||||
func errorHandler(w http.ResponseWriter, r *http.Request, err error, status int) {
|
||||
log.Printf("errorHandler: %v", err)
|
||||
log.Printf("errorHandler: err=%v\n", err)
|
||||
|
||||
w.WriteHeader(status)
|
||||
|
||||
@@ -234,8 +242,34 @@ func errorHandler(w http.ResponseWriter, r *http.Request, err error, status int)
|
||||
}
|
||||
fmt.Print(strings.Join(lines, "\n"))
|
||||
|
||||
render(w, r, "error", map[string]interface{}{"Message": "Some unexpected error occurred!"})
|
||||
// TODO: send email eventually with info on the error
|
||||
if viper.GetBool("config.complete") {
|
||||
render(w, r, "error", map[string]interface{}{"Message": "Some unexpected error occurred!"})
|
||||
} else {
|
||||
// ONLY in the setup phase to prevent leaking too much details to users
|
||||
var FileErrors []interface{}
|
||||
data := getLog(w, r, "cert")
|
||||
if data != "" {
|
||||
FileErrors = append(FileErrors, map[string]interface{}{"FileName": "/etc/nginx/ssl/acme_tiny.log", "Content": data})
|
||||
}
|
||||
data = getLog(w, r, "commander")
|
||||
if data != "" {
|
||||
FileErrors = append(FileErrors, map[string]interface{}{"FileName": "/home/labca/logs/commander.log", "Content": data})
|
||||
}
|
||||
data = getLog(w, r, "labca-notail")
|
||||
if data != "" {
|
||||
FileErrors = append(FileErrors, map[string]interface{}{"FileName": "docker-compose logs labca", "Content": data})
|
||||
}
|
||||
data = getLog(w, r, "boulder-notail")
|
||||
if data != "" {
|
||||
FileErrors = append(FileErrors, map[string]interface{}{"FileName": "docker-compose logs boulder", "Content": data})
|
||||
}
|
||||
data = getLog(w, r, "labca-err")
|
||||
if data != "" {
|
||||
FileErrors = append(FileErrors, map[string]interface{}{"FileName": "/var/log/labca.err", "Content": data})
|
||||
}
|
||||
|
||||
render(w, r, "error", map[string]interface{}{"Message": "Some unexpected error occurred!", "FileErrors": FileErrors})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -340,7 +374,7 @@ func loginHandler(w http.ResponseWriter, r *http.Request) {
|
||||
RequestBase: r.Header.Get("X-Request-Base"),
|
||||
}
|
||||
|
||||
if reg.Validate(false, false) == false {
|
||||
if !reg.Validate(false, false) {
|
||||
render(w, r, "login", map[string]interface{}{"User": reg, "IsLogin": true})
|
||||
return
|
||||
}
|
||||
@@ -584,7 +618,7 @@ func (cfg *EmailConfig) Validate() bool {
|
||||
cfg.Errors["EmailPwd"] = "Could not encrypt this password: " + err.Error()
|
||||
}
|
||||
|
||||
if cfg.DoEmail == false {
|
||||
if !cfg.DoEmail {
|
||||
return len(cfg.Errors) == 0
|
||||
}
|
||||
|
||||
@@ -945,7 +979,7 @@ func _managePost(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
}
|
||||
if !actionKnown {
|
||||
errorHandler(w, r, fmt.Errorf("Unknown manage action '%s'", action), http.StatusBadRequest)
|
||||
errorHandler(w, r, fmt.Errorf("unknown manage action '%s'", action), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1164,7 +1198,7 @@ func logsHandler(w http.ResponseWriter, r *http.Request) {
|
||||
wsurl = ""
|
||||
data = getLog(w, r, logType)
|
||||
default:
|
||||
errorHandler(w, r, fmt.Errorf("Unknown log type '%s'", logType), http.StatusBadRequest)
|
||||
errorHandler(w, r, fmt.Errorf("unknown log type '%s'", logType), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1233,7 +1267,7 @@ func showLog(ws *websocket.Conn, logType string) {
|
||||
scanner := bufio.NewScanner(conn)
|
||||
for scanner.Scan() {
|
||||
msg := scanner.Text()
|
||||
if logType != "audit" || strings.Index(msg, "[AUDIT]") > -1 {
|
||||
if logType != "audit" || strings.Contains(msg, "[AUDIT]") {
|
||||
ws.SetWriteDeadline(time.Now().Add(writeWait))
|
||||
if err := ws.WriteMessage(websocket.TextMessage, []byte(msg)); err != nil {
|
||||
// Probably "websocket: close sent"
|
||||
@@ -1245,8 +1279,6 @@ func showLog(ws *websocket.Conn, logType string) {
|
||||
wsErrorHandler(err)
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func reader(ws *websocket.Conn) {
|
||||
@@ -1300,7 +1332,7 @@ func wsHandler(w http.ResponseWriter, r *http.Request) {
|
||||
case "labca":
|
||||
case "web":
|
||||
default:
|
||||
errorHandler(w, r, fmt.Errorf("Unknown log type '%s'", logType), http.StatusBadRequest)
|
||||
errorHandler(w, r, fmt.Errorf("unknown log type '%s'", logType), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1398,7 +1430,7 @@ func _certCreate(w http.ResponseWriter, r *http.Request, certBase string, isRoot
|
||||
ci.Certificate = r.Form.Get("certificate")
|
||||
ci.RequestBase = r.Header.Get("X-Request-Base")
|
||||
|
||||
if ci.Validate() == false {
|
||||
if !ci.Validate() {
|
||||
render(w, r, "cert:manage", map[string]interface{}{"CertificateInfo": ci, "Progress": _progress(certBase), "HelpText": _helptext(certBase)})
|
||||
return false
|
||||
}
|
||||
@@ -1664,7 +1696,7 @@ func _setupAdminUser(w http.ResponseWriter, r *http.Request) bool {
|
||||
RequestBase: r.Header.Get("X-Request-Base"),
|
||||
}
|
||||
|
||||
if reg.Validate(true, false) == false {
|
||||
if !reg.Validate(true, false) {
|
||||
render(w, r, "register:manage", map[string]interface{}{"User": reg, "IsLogin": true, "Progress": _progress("register"), "HelpText": _helptext("register")})
|
||||
return false
|
||||
}
|
||||
@@ -1727,7 +1759,7 @@ func _setupBaseConfig(w http.ResponseWriter, r *http.Request) bool {
|
||||
RequestBase: r.Header.Get("X-Request-Base"),
|
||||
}
|
||||
|
||||
if cfg.Validate(false) == false {
|
||||
if !cfg.Validate(false) {
|
||||
render(w, r, "setup:manage", map[string]interface{}{"SetupConfig": cfg, "Progress": _progress("setup"), "HelpText": _helptext("setup")})
|
||||
return false
|
||||
}
|
||||
@@ -1759,7 +1791,7 @@ func _setupBaseConfig(w http.ResponseWriter, r *http.Request) bool {
|
||||
}
|
||||
|
||||
func setupHandler(w http.ResponseWriter, r *http.Request) {
|
||||
if viper.GetBool("config.complete") == true {
|
||||
if viper.GetBool("config.complete") {
|
||||
render(w, r, "index:manage", map[string]interface{}{"Message": template.HTML("Setup already completed! Go <a href=\"" + r.Header.Get("X-Request-Base") + "/\">home</a>")})
|
||||
return
|
||||
}
|
||||
@@ -1852,33 +1884,60 @@ func finalHandler(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
// Don't let the retry mechanism trigger a certificate request and restart!
|
||||
if r.Header.Get("X-Requested-With") == "XMLHttpRequest" {
|
||||
render(w, r, "index", map[string]interface{}{"Message": "Retry OK"})
|
||||
} else {
|
||||
// 9. Setup our own web certificate
|
||||
if !_hostCommand(w, r, "acme-request") {
|
||||
http.Redirect(w, r, r.Header.Get("X-Request-Base")+"/logs/cert", http.StatusSeeOther)
|
||||
return
|
||||
t := viper.GetTime("config.cert_requested")
|
||||
if !t.IsZero() && t.After(time.Now().Add(-5*time.Minute)) {
|
||||
// Too soon
|
||||
if r.Header.Get("X-Requested-With") == "XMLHttpRequest" {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
if viper.GetBool("config.error") {
|
||||
viper.Set("config.cert_requested", nil)
|
||||
viper.WriteConfig()
|
||||
}
|
||||
json.NewEncoder(w).Encode(map[string]interface{}{"complete": viper.GetBool("config.complete"), "error": viper.GetBool("config.error")})
|
||||
} else {
|
||||
render(w, r, "polling:manage", map[string]interface{}{"Progress": _progress("polling"), "HelpText": _helptext("polling")})
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// 10. remove the temporary bit from nginx config
|
||||
if !_hostCommand(w, r, "nginx-remove-redirect") {
|
||||
return
|
||||
}
|
||||
|
||||
// 11. reload nginx
|
||||
if !_hostCommand(w, r, "nginx-reload") {
|
||||
return
|
||||
}
|
||||
|
||||
viper.Set("config.complete", true)
|
||||
viper.Set("config.cert_requested", time.Now())
|
||||
if viper.GetBool("config.error") {
|
||||
viper.Set("config.error", false)
|
||||
}
|
||||
viper.WriteConfig()
|
||||
// 9. Setup our own web certificate
|
||||
if !_hostCommand(w, r, "acme-request") {
|
||||
viper.Set("config.error", true)
|
||||
viper.WriteConfig()
|
||||
http.Redirect(w, r, r.Header.Get("X-Request-Base")+"/logs/cert", http.StatusSeeOther)
|
||||
return
|
||||
}
|
||||
|
||||
// 10. remove the temporary bit from nginx config
|
||||
if !_hostCommand(w, r, "nginx-remove-redirect") {
|
||||
return
|
||||
}
|
||||
|
||||
// 11. reload nginx
|
||||
if !_hostCommand(w, r, "nginx-reload") {
|
||||
return
|
||||
}
|
||||
|
||||
viper.Set("config.complete", true)
|
||||
viper.WriteConfig()
|
||||
|
||||
if r.Header.Get("X-Requested-With") == "XMLHttpRequest" {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
json.NewEncoder(w).Encode(map[string]interface{}{"complete": viper.GetBool("config.complete")})
|
||||
} else {
|
||||
render(w, r, "final:manage", map[string]interface{}{"RequestBase": r.Header.Get("X-Request-Base"), "Progress": _progress("final"), "HelpText": _helptext("final")})
|
||||
}
|
||||
}
|
||||
|
||||
func showErrorHandler(w http.ResponseWriter, r *http.Request) {
|
||||
errorHandler(w, r, nil, http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
// RangeStructer takes the first argument, which must be a struct, and
|
||||
// returns the value of each field in a slice. It will return nil
|
||||
// if there are no arguments or first argument is not a struct
|
||||
@@ -2064,7 +2123,7 @@ func certificateHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
func certRevokeHandler(w http.ResponseWriter, r *http.Request) {
|
||||
if !viper.GetBool("config.complete") {
|
||||
errorHandler(w, r, errors.New("Method not allowed at this point"), http.StatusMethodNotAllowed)
|
||||
errorHandler(w, r, errors.New("method not allowed at this point"), http.StatusMethodNotAllowed)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -2402,6 +2461,7 @@ func main() {
|
||||
r.HandleFunc("/about", aboutHandler).Methods("GET")
|
||||
r.HandleFunc("/manage", manageHandler).Methods("GET", "POST")
|
||||
r.HandleFunc("/final", finalHandler).Methods("GET")
|
||||
r.HandleFunc("/error", showErrorHandler).Methods("GET")
|
||||
r.HandleFunc("/login", loginHandler).Methods("GET", "POST")
|
||||
r.HandleFunc("/logout", logoutHandler).Methods("GET")
|
||||
r.HandleFunc("/logs/{type}", logsHandler).Methods("GET")
|
||||
|
||||
@@ -1,4 +1,13 @@
|
||||
{{ define "body" }}
|
||||
<h3>OOPS</h3>
|
||||
<p>{{ .Message }}</p>
|
||||
{{ if .FileErrors }}
|
||||
<br/>
|
||||
<h4>Diagnostics</h4>
|
||||
<p>These log files might help you determine what the problem is:</p>
|
||||
{{ range $item := .FileErrors }}
|
||||
<p><b>{{ $item.FileName }}</b></p>
|
||||
<pre>{{ $item.Content }}</pre>
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
|
||||
49
install
49
install
@@ -24,7 +24,7 @@ dockerComposeVersion="1.28.5"
|
||||
|
||||
labcaUrl="https://github.com/hakwerk/labca/"
|
||||
boulderUrl="https://github.com/letsencrypt/boulder/"
|
||||
boulderTag="release-2021-08-02"
|
||||
boulderTag="release-2021-08-31"
|
||||
|
||||
#
|
||||
# Color configuration
|
||||
@@ -520,51 +520,54 @@ config_boulder() {
|
||||
msg_info "$msg"
|
||||
|
||||
cd "$boulderDir"
|
||||
sudo -u labca -H patch -p1 < $cloneDir/docker-compose.patch &>>$installLog
|
||||
sudo -u labca -H patch -p1 < $cloneDir/patches/docker-compose.patch &>>$installLog
|
||||
cp docker-compose.yml "$boulderLabCADir/.backup/"
|
||||
|
||||
sudo -u labca -H patch -p1 < $cloneDir/cmd_shell.patch &>>$installLog
|
||||
sudo -u labca -H patch -p1 < $cloneDir/patches/cmd_shell.patch &>>$installLog
|
||||
cp cmd/shell.go "$boulderLabCADir/.backup/"
|
||||
|
||||
sudo -u labca -H patch -p1 < $cloneDir/core_interfaces.patch &>>$installLog
|
||||
sudo -u labca -H patch -p1 < $cloneDir/patches/core_interfaces.patch &>>$installLog
|
||||
cp core/interfaces.go "$boulderLabCADir/.backup/"
|
||||
|
||||
sudo -u labca -H patch -p1 < $cloneDir/policy_pa.patch &>>$installLog
|
||||
sudo -u labca -H patch -p1 < $cloneDir/patches/policy_pa.patch &>>$installLog
|
||||
cp policy/pa.go "$boulderLabCADir/.backup/"
|
||||
|
||||
sudo -u labca -H patch -p1 < $cloneDir/ra_ra.patch &>>$installLog
|
||||
sudo -u labca -H patch -p1 < $cloneDir/patches/ra_ra.patch &>>$installLog
|
||||
cp ra/ra.go "$boulderLabCADir/.backup/"
|
||||
|
||||
sudo -u labca -H patch -p1 < $cloneDir/reloader_reloader.patch &>>$installLog
|
||||
sudo -u labca -H patch -p1 < $cloneDir/patches/reloader_reloader.patch &>>$installLog
|
||||
cp reloader/reloader.go "$boulderLabCADir/.backup/"
|
||||
|
||||
sudo -u labca -H patch -p1 < $cloneDir/mail_mailer.patch &>>$installLog
|
||||
sudo -u labca -H patch -p1 < $cloneDir/patches/mail_mailer.patch &>>$installLog
|
||||
cp mail/mailer.go "$boulderLabCADir/.backup/"
|
||||
|
||||
sudo -u labca -H patch -p1 < $cloneDir/expiration-mailer_main.patch &>>$installLog
|
||||
sudo -u labca -H patch -p1 < $cloneDir/patches/expiration-mailer_main.patch &>>$installLog
|
||||
cp cmd/expiration-mailer/main.go "$boulderLabCADir/.backup/"
|
||||
|
||||
sudo -u labca -H patch -p1 < $cloneDir/notify-mailer_main.patch &>>$installLog
|
||||
sudo -u labca -H patch -p1 < $cloneDir/patches/notify-mailer_main.patch &>>$installLog
|
||||
cp cmd/notify-mailer/main.go "$boulderLabCADir/.backup/"
|
||||
|
||||
sudo -u labca -H patch -p1 < $cloneDir/contact-auditor_main.patch &>>$installLog
|
||||
sudo -u labca -H patch -p1 < $cloneDir/patches/contact-auditor_main.patch &>>$installLog
|
||||
cp cmd/contact-auditor/main.go "$boulderLabCADir/.backup/"
|
||||
|
||||
sudo -u labca -H patch -p1 < $cloneDir/bad-key-revoker_main.patch &>>$installLog
|
||||
sudo -u labca -H patch -p1 < $cloneDir/patches/bad-key-revoker_main.patch &>>$installLog
|
||||
cp cmd/bad-key-revoker/main.go "$boulderLabCADir/.backup/"
|
||||
|
||||
sudo -u labca -H patch -p1 -o "$boulderLabCADir/entrypoint.sh" < $cloneDir/entrypoint.patch &>>$installLog
|
||||
sudo -u labca -H patch -p1 -o "$boulderLabCADir/startservers.py" < $cloneDir/startservers.patch &>>$installLog
|
||||
sudo -u labca -H patch -p1 < $cloneDir/startservers.patch &>>$installLog
|
||||
sudo -u labca -H patch -p1 < $cloneDir/patches/log-validator_main.patch &>>$installLog
|
||||
cp cmd/log-validator/main.go "$boulderLabCADir/.backup/"
|
||||
|
||||
sudo -u labca -H patch -p1 -o "$boulderLabCADir/config/ca-a.json" < $cloneDir/test_config_ca_a.patch &>>$installLog
|
||||
sudo -u labca -H patch -p1 -o "$boulderLabCADir/config/ca-b.json" < $cloneDir/test_config_ca_b.patch &>>$installLog
|
||||
sudo -u labca -H patch -p1 -o "$boulderLabCADir/entrypoint.sh" < $cloneDir/patches/entrypoint.patch &>>$installLog
|
||||
sudo -u labca -H patch -p1 -o "$boulderLabCADir/startservers.py" < $cloneDir/patches/startservers.patch &>>$installLog
|
||||
sudo -u labca -H patch -p1 < $cloneDir/patches/startservers.patch &>>$installLog
|
||||
|
||||
sudo -u labca -H patch -p1 -o "$boulderLabCADir/config/expiration-mailer.json" < $cloneDir/config_expiration-mailer.patch &>>$installLog
|
||||
sudo -u labca -H patch -p1 -o "$boulderLabCADir/config/notify-mailer.json" < $cloneDir/config_notify-mailer.patch &>>$installLog
|
||||
sudo -u labca -H patch -p1 -o "$boulderLabCADir/config/bad-key-revoker.json" < $cloneDir/config_bad-key-revoker.patch &>>$installLog
|
||||
sudo -u labca -H patch -p1 -o "$boulderLabCADir/config/ocsp-responder.json" < $cloneDir/config_ocsp-responder.patch &>>$installLog
|
||||
sudo -u labca -H patch -p1 -o "$boulderLabCADir/config/publisher.json" < $cloneDir/config_publisher.patch &>>$installLog
|
||||
sudo -u labca -H patch -p1 -o "$boulderLabCADir/config/ca-a.json" < $cloneDir/patches/test_config_ca_a.patch &>>$installLog
|
||||
sudo -u labca -H patch -p1 -o "$boulderLabCADir/config/ca-b.json" < $cloneDir/patches/test_config_ca_b.patch &>>$installLog
|
||||
|
||||
sudo -u labca -H patch -p1 -o "$boulderLabCADir/config/expiration-mailer.json" < $cloneDir/patches/config_expiration-mailer.patch &>>$installLog
|
||||
sudo -u labca -H patch -p1 -o "$boulderLabCADir/config/notify-mailer.json" < $cloneDir/patches/config_notify-mailer.patch &>>$installLog
|
||||
sudo -u labca -H patch -p1 -o "$boulderLabCADir/config/bad-key-revoker.json" < $cloneDir/patches/config_bad-key-revoker.patch &>>$installLog
|
||||
sudo -u labca -H patch -p1 -o "$boulderLabCADir/config/ocsp-responder.json" < $cloneDir/patches/config_ocsp-responder.patch &>>$installLog
|
||||
sudo -u labca -H patch -p1 -o "$boulderLabCADir/config/publisher.json" < $cloneDir/patches/config_publisher.patch &>>$installLog
|
||||
|
||||
sed -i -e "s|https://letsencrypt.org/docs/rate-limits/|http://$LABCA_FQDN/rate-limits|" errors/errors.go &>>$installLog
|
||||
cp errors/errors.go "$boulderLabCADir/.backup/"
|
||||
@@ -575,7 +578,7 @@ config_boulder() {
|
||||
mkdir -p "cmd/mail-tester"
|
||||
cp $cloneDir/mail-tester.go cmd/mail-tester/main.go
|
||||
|
||||
sudo -u labca -H patch -p1 < $cloneDir/db_migrations.patch &>>$installLog
|
||||
sudo -u labca -H patch -p1 < $cloneDir/patches/db_migrations.patch &>>$installLog
|
||||
cp sa/_db/migrations/20210223140000_CombinedSchema.sql "$boulderLabCADir/.backup/"
|
||||
|
||||
mkdir -p $baseDir/backup
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
diff --git a/cmd/bad-key-revoker/main.go b/cmd/bad-key-revoker/main.go
|
||||
index 2d6d17f16..e09948cfc 100644
|
||||
index 3f3a953d3..c02b4dfc1 100644
|
||||
--- a/cmd/bad-key-revoker/main.go
|
||||
+++ b/cmd/bad-key-revoker/main.go
|
||||
@@ -15,6 +15,7 @@ import (
|
||||
@@ -10,7 +10,7 @@ index 2d6d17f16..e09948cfc 100644
|
||||
"github.com/letsencrypt/boulder/cmd"
|
||||
"github.com/letsencrypt/boulder/core"
|
||||
"github.com/letsencrypt/boulder/db"
|
||||
@@ -348,6 +349,9 @@ func main() {
|
||||
@@ -352,6 +353,9 @@ func main() {
|
||||
TLS cmd.TLSConfig
|
||||
RAService *cmd.GRPCClientConfig
|
||||
|
||||
@@ -20,7 +20,7 @@ index 2d6d17f16..e09948cfc 100644
|
||||
// MaximumRevocations specifies the maximum number of certificates associated with
|
||||
// a key hash that bad-key-revoker will attempt to revoke. If the number of certificates
|
||||
// is higher than MaximumRevocations bad-key-revoker will error out and refuse to
|
||||
@@ -375,6 +379,12 @@ func main() {
|
||||
@@ -385,6 +389,12 @@ func main() {
|
||||
|
||||
Syslog cmd.SyslogConfig
|
||||
Beeline cmd.BeelineConfig
|
||||
@@ -33,7 +33,7 @@ index 2d6d17f16..e09948cfc 100644
|
||||
}
|
||||
configPath := flag.String("config", "", "File path to the configuration file for this service")
|
||||
flag.Parse()
|
||||
@@ -424,6 +434,32 @@ func main() {
|
||||
@@ -434,6 +444,32 @@ func main() {
|
||||
cmd.FailOnError(err, "Failed to load credentials and create gRPC connection to RA")
|
||||
rac := rapb.NewRegistrationAuthorityClient(conn)
|
||||
|
||||
@@ -66,7 +66,7 @@ index 2d6d17f16..e09948cfc 100644
|
||||
var smtpRoots *x509.CertPool
|
||||
if config.BadKeyRevoker.Mailer.SMTPTrustedRootFile != "" {
|
||||
pem, err := ioutil.ReadFile(config.BadKeyRevoker.Mailer.SMTPTrustedRootFile)
|
||||
@@ -445,6 +481,7 @@ func main() {
|
||||
@@ -455,6 +491,7 @@ func main() {
|
||||
config.BadKeyRevoker.Mailer.Username,
|
||||
smtpPassword,
|
||||
smtpRoots,
|
||||
@@ -1,8 +1,8 @@
|
||||
diff --git a/core/interfaces.go b/core/interfaces.go
|
||||
index 4e03131cb..43468ca3b 100644
|
||||
index d19eb4fb8..3ae50d737 100644
|
||||
--- a/core/interfaces.go
|
||||
+++ b/core/interfaces.go
|
||||
@@ -94,6 +94,7 @@ type PolicyAuthority interface {
|
||||
@@ -91,6 +91,7 @@ type PolicyAuthority interface {
|
||||
WillingToIssueWildcards(identifiers []identifier.ACMEIdentifier) error
|
||||
ChallengesFor(domain identifier.ACMEIdentifier) ([]Challenge, error)
|
||||
ChallengeTypeEnabled(t AcmeChallenge) bool
|
||||
@@ -1,5 +1,5 @@
|
||||
diff --git a/cmd/expiration-mailer/main.go b/cmd/expiration-mailer/main.go
|
||||
index 9f56157dd..8cc77676c 100644
|
||||
index f6b02976e..0b00b794d 100644
|
||||
--- a/cmd/expiration-mailer/main.go
|
||||
+++ b/cmd/expiration-mailer/main.go
|
||||
@@ -20,6 +20,7 @@ import (
|
||||
@@ -9,8 +9,8 @@ index 9f56157dd..8cc77676c 100644
|
||||
+ "github.com/letsencrypt/boulder/bdns"
|
||||
"github.com/letsencrypt/boulder/cmd"
|
||||
"github.com/letsencrypt/boulder/core"
|
||||
"github.com/letsencrypt/boulder/db"
|
||||
@@ -35,7 +36,7 @@ import (
|
||||
corepb "github.com/letsencrypt/boulder/core/proto"
|
||||
@@ -36,7 +37,7 @@ import (
|
||||
|
||||
const (
|
||||
defaultNagCheckInterval = 24 * time.Hour
|
||||
@@ -19,7 +19,7 @@ index 9f56157dd..8cc77676c 100644
|
||||
)
|
||||
|
||||
type regStore interface {
|
||||
@@ -384,6 +385,9 @@ type config struct {
|
||||
@@ -385,6 +386,9 @@ type config struct {
|
||||
TLS cmd.TLSConfig
|
||||
SAService *cmd.GRPCClientConfig
|
||||
|
||||
@@ -29,7 +29,7 @@ index 9f56157dd..8cc77676c 100644
|
||||
// Path to a file containing a list of trusted root certificates for use
|
||||
// during the SMTP connection (as opposed to the gRPC connections).
|
||||
SMTPTrustedRootFile string
|
||||
@@ -393,6 +397,12 @@ type config struct {
|
||||
@@ -394,6 +398,12 @@ type config struct {
|
||||
|
||||
Syslog cmd.SyslogConfig
|
||||
Beeline cmd.BeelineConfig
|
||||
@@ -42,7 +42,7 @@ index 9f56157dd..8cc77676c 100644
|
||||
}
|
||||
|
||||
func initStats(stats prometheus.Registerer) mailerStats {
|
||||
@@ -510,6 +520,32 @@ func main() {
|
||||
@@ -511,6 +521,32 @@ func main() {
|
||||
cmd.FailOnError(err, "Failed to load credentials and create gRPC connection to SA")
|
||||
sac := bgrpc.NewStorageAuthorityClient(sapb.NewStorageAuthorityClient(conn))
|
||||
|
||||
@@ -75,7 +75,7 @@ index 9f56157dd..8cc77676c 100644
|
||||
var smtpRoots *x509.CertPool
|
||||
if c.Mailer.SMTPTrustedRootFile != "" {
|
||||
pem, err := ioutil.ReadFile(c.Mailer.SMTPTrustedRootFile)
|
||||
@@ -545,6 +581,7 @@ func main() {
|
||||
@@ -546,6 +582,7 @@ func main() {
|
||||
c.Mailer.Username,
|
||||
smtpPassword,
|
||||
smtpRoots,
|
||||
15
patches/log-validator_main.patch
Normal file
15
patches/log-validator_main.patch
Normal file
@@ -0,0 +1,15 @@
|
||||
diff --git a/cmd/log-validator/main.go b/cmd/log-validator/main.go
|
||||
index fdab2ac6..bb136880 100644
|
||||
--- a/cmd/log-validator/main.go
|
||||
+++ b/cmd/log-validator/main.go
|
||||
@@ -52,8 +52,8 @@ func lineValid(text string) error {
|
||||
if strings.Contains(text, errorPrefix) {
|
||||
return nil
|
||||
}
|
||||
- // Check the extracted checksum against the computed checksum
|
||||
- if computedChecksum := blog.LogLineChecksum(line); checksum != computedChecksum {
|
||||
+ // Check the extracted checksum against the computed checksum, but ignore "message repeated X times" lines
|
||||
+ if computedChecksum := blog.LogLineChecksum(line); checksum != computedChecksum && checksum != "message" {
|
||||
return fmt.Errorf("%s invalid checksum (expected %q, got %q)", errorPrefix, computedChecksum, checksum)
|
||||
}
|
||||
return nil
|
||||
@@ -1,5 +1,5 @@
|
||||
diff --git a/ra/ra.go b/ra/ra.go
|
||||
index 58fa25ca8..09d2a3579 100644
|
||||
index 1023d0232..3f8d86d87 100644
|
||||
--- a/ra/ra.go
|
||||
+++ b/ra/ra.go
|
||||
@@ -31,7 +31,6 @@ import (
|
||||
@@ -10,7 +10,7 @@ index 58fa25ca8..09d2a3579 100644
|
||||
"github.com/letsencrypt/boulder/probs"
|
||||
pubpb "github.com/letsencrypt/boulder/publisher/proto"
|
||||
rapb "github.com/letsencrypt/boulder/ra/proto"
|
||||
@@ -446,7 +445,7 @@ func (ra *RegistrationAuthorityImpl) validateContacts(ctx context.Context, conta
|
||||
@@ -435,7 +434,7 @@ func (ra *RegistrationAuthorityImpl) validateContacts(ctx context.Context, conta
|
||||
contact,
|
||||
)
|
||||
}
|
||||
@@ -2,7 +2,7 @@ diff --git a/test/config/ca-a.json b/test/config/ca-a.json
|
||||
index 92b32f094..e220d7d4f 100644
|
||||
--- a/test/config/ca-a.json
|
||||
+++ b/test/config/ca-a.json
|
||||
@@ -58,19 +58,7 @@
|
||||
@@ -60,19 +60,7 @@
|
||||
"crlURL": "http://example.com/crl",
|
||||
"location": {
|
||||
"configFile": "test/test-ca.key-pkcs11.json",
|
||||
@@ -2,7 +2,7 @@ diff --git a/test/config/ca-b.json b/test/config/ca-b.json
|
||||
index 6c7d9d272..4e428bc4a 100644
|
||||
--- a/test/config/ca-b.json
|
||||
+++ b/test/config/ca-b.json
|
||||
@@ -58,19 +58,7 @@
|
||||
@@ -60,19 +60,7 @@
|
||||
"crlURL": "http://example.com/crl",
|
||||
"location": {
|
||||
"configFile": "test/test-ca.key-pkcs11.json",
|
||||
1
www/css/bootstrap.min.css.map
Normal file
1
www/css/bootstrap.min.css.map
Normal file
File diff suppressed because one or more lines are too long
@@ -182,7 +182,6 @@ $(function() {
|
||||
positionFooter();
|
||||
});
|
||||
|
||||
|
||||
$("#restart-button").click(function(evt) {
|
||||
$("#pre-restart-1").hide();
|
||||
$("#pre-restart-2").hide();
|
||||
@@ -190,53 +189,69 @@ $(function() {
|
||||
$("#restarting").show();
|
||||
$(window).resize();
|
||||
|
||||
var args = window.location.href.split('?')[1].split('=');
|
||||
var args = [ "unknown" ];
|
||||
if (window.location.href.indexOf('?') > 0 ) {
|
||||
var tmp = window.location.href.split('?');
|
||||
if (tmp.length > 1) {
|
||||
args = tmp[1].split('=');
|
||||
}
|
||||
}
|
||||
var secret = "";
|
||||
var nextPath = "";
|
||||
if (args[0] == "restart") {
|
||||
secret = args[1];
|
||||
nextPath = "/restart";
|
||||
}
|
||||
|
||||
var pollTimer;
|
||||
|
||||
var baseUrl = window.location.href.substr(0, window.location.href.indexOf("?")).replace("/wait", "");
|
||||
$.ajax(baseUrl + "/restart", {
|
||||
var baseUrl = window.location.href;
|
||||
if (baseUrl.indexOf("?") > 0) {
|
||||
baseUrl = baseUrl.substr(0, baseUrl.indexOf("?"));
|
||||
}
|
||||
if (baseUrl.endsWith("/wait")) {
|
||||
baseUrl = baseUrl.substr(0, baseUrl.length-5);
|
||||
}
|
||||
$.ajax(baseUrl + nextPath, {
|
||||
data: {
|
||||
token: secret,
|
||||
},
|
||||
timeout: 3000
|
||||
timeout: 30000
|
||||
})
|
||||
.done(function(data) {
|
||||
clearInterval(pollTimer);
|
||||
window.location.href = baseUrl + "/setup";
|
||||
})
|
||||
.fail(function(xhr, status, err) {
|
||||
if (err === "timeout") {
|
||||
// Assume that the restart was initiated... Wait for server to be available again.
|
||||
var ctr = 0;
|
||||
pollTimer = setInterval(pollServer, 3000);
|
||||
pollServer();
|
||||
nextPath = "";
|
||||
// Assume that the restart was initiated... Wait for server to be available again.
|
||||
var ctr = 0;
|
||||
pollTimer = setInterval(pollServer, 3000);
|
||||
|
||||
function pollServer() {
|
||||
if (ctr > 59) {
|
||||
function pollServer() {
|
||||
if (ctr > 59) {
|
||||
clearInterval(pollTimer);
|
||||
$("img#restart-spinner").parent().text("timeout").addClass("error");
|
||||
} else if (ctr < 10) {
|
||||
// No need to try immediately, the server is restarting
|
||||
ctr++;
|
||||
} else {
|
||||
$.ajax(baseUrl + nextPath, {
|
||||
timeout: 2500
|
||||
})
|
||||
.done(function(data) {
|
||||
clearInterval(pollTimer);
|
||||
$("img#restart-spinner").parent().text("timeout").addClass("error");
|
||||
} else {
|
||||
$.ajax(baseUrl + "/setup", {
|
||||
timeout: 2500
|
||||
})
|
||||
.done(function(data) {
|
||||
window.location.href = baseUrl;
|
||||
})
|
||||
.fail(function(xhr, status, err) {
|
||||
ctr++;
|
||||
if ((typeof err === 'undefined' || err === "") && status === "error") {
|
||||
// Probably because the certificate has changed
|
||||
clearInterval(pollTimer);
|
||||
window.location.href = baseUrl + "/setup";
|
||||
})
|
||||
.fail(function(xhr, status, err) {
|
||||
ctr++;
|
||||
});
|
||||
}
|
||||
window.location.href = baseUrl;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
} else {
|
||||
clearInterval(pollTimer);
|
||||
$("img#restart-spinner").parent().text(err).addClass("error");
|
||||
}
|
||||
});
|
||||
|
||||
@@ -246,23 +261,37 @@ $(function() {
|
||||
if ( $("img#wrapup-spinner").length ) {
|
||||
var targetUrl = window.location.href.replace("/setup", "/final");
|
||||
var ctr = 0;
|
||||
var pollTimer = setInterval(pollServer, 3000);
|
||||
pollServer();
|
||||
var pollTimer = setInterval(pollServer, 5000);
|
||||
|
||||
function pollServer() {
|
||||
if (ctr > 20) {
|
||||
if (ctr > 60) {
|
||||
clearInterval(pollTimer);
|
||||
$("img#wrapup-spinner").parent().text("timeout").addClass("error");
|
||||
} else if (ctr < 5) {
|
||||
// No need to try immediately, the server won't be ready this quick
|
||||
ctr++;
|
||||
} else {
|
||||
$.ajax(targetUrl, {
|
||||
timeout: 2500
|
||||
timeout: 4500
|
||||
})
|
||||
.done(function(data) {
|
||||
clearInterval(pollTimer);
|
||||
window.location.href = targetUrl;
|
||||
if (data.error) {
|
||||
clearInterval(pollTimer);
|
||||
targetUrl = targetUrl.replace("/final", "/error");
|
||||
window.location.href = targetUrl;
|
||||
} else if (data.complete) {
|
||||
clearInterval(pollTimer);
|
||||
targetUrl = targetUrl.replace("/final", "");
|
||||
window.location.href = targetUrl;
|
||||
}
|
||||
})
|
||||
.fail(function(xhr, status, err) {
|
||||
ctr++;
|
||||
if ((typeof err === 'undefined' || err === "") && status === "error") {
|
||||
// Probably because the certificate has changed
|
||||
clearInterval(pollTimer);
|
||||
window.location.href = targetUrl;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user