summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile48
-rw-r--r--config.go100
-rw-r--r--generate/include.go30
-rw-r--r--main.go35
-rw-r--r--templates.go4
-rw-r--r--templates/block_facebook.tmpl3
-rw-r--r--templates/cache_static.tmpl3
-rw-r--r--templates/pagespeed.tmpl13
-rw-r--r--templates/robots.tmpl7
-rw-r--r--templates/server.tmpl43
-rw-r--r--templates/ssl.tmpl8
11 files changed, 294 insertions, 0 deletions
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..23e5ed0
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,48 @@
+CONFIG=config.json
+TARGET=ngxconf
+NGXCONF=nginx.conf
+GENERATED=templates.go
+SOURCES=$(wildcard *.go) $(GENERATED)
+
+all: build config
+ @echo "Run 'make preview' to view the rendered template or 'make save' to save it in $(NGXCONF)"
+
+build: $(TARGET)
+
+$(TARGET): $(SOURCES)
+ @echo "Generating Go sources..."
+ @go generate || echo "Failed. We need at least Go version 1.4 to generate code. $(TARGET) still works but you ned to specify the full path to your template directory."
+ go build
+
+config: $(CONFIG)
+
+$(CONFIG): $(TARGET)
+ ./$(TARGET) -genconfig $(CONFIG)
+ @echo ""
+
+save: build
+ @if [ ! -f $(CONFIG) ]; then make config; fi
+ ./$(TARGET) -config $(CONFIG) > $(NGXCONF)
+
+preview: build
+ @if [ ! -f $(CONFIG) ]; then make config; fi
+ @./$(TARGET) -config $(CONFIG)
+
+edit: $(CONFIG)
+ $(EDITOR) $(CONFIG)
+
+clean:
+ $(RM) $(RMFLAGS) $(CONFIG) $(TARGET) $(NGXCONF) $(GENERATED)
+ @echo "package main" > $(GENERATED); \
+ echo "// To be replaced by go generate" >> $(GENERATED); \
+ echo "func isGenerated() bool { return false }" >> $(GENERATED); \
+ echo "func getTemplate() string { return \"\" }" >> $(GENERATED)
+
+help:
+ @echo "Generates a standard nginx config file"
+ @echo "make build -- compile"
+ @echo "make config -- generate config"
+ @echo "make save -- render template and save in $(NGXCONF)"
+ @echo "make preview -- preview rendered template"
+ @echo "make edit -- edit $(CONFIG)"
+ @echo "make clean -- removes generated files"
diff --git a/config.go b/config.go
new file mode 100644
index 0000000..ba1b237
--- /dev/null
+++ b/config.go
@@ -0,0 +1,100 @@
+package main
+
+import (
+ "encoding/json"
+ "fmt"
+ "io/ioutil"
+ "log"
+ "os"
+)
+
+var Conf *Configuration
+
+type Configuration struct {
+ TemplateDir string
+ Port int
+ PortSSL int
+ SSL bool
+ DHParam string
+ SPDY string
+ Root string
+ ServerName []string
+ Index []string
+ AccessLog string
+ ErrorLog string
+ SSL_Cert string
+ SSL_Cert_Key string
+ UsePHP bool
+ PHP_TCP bool
+ Robots bool
+ RobotsDisallow []string
+ RobotsAllow []string
+ Cache_Static bool
+ Pagespeed bool
+ Block_Facebook bool
+ UpstreamName string
+ Upstream []string
+}
+
+func NewConfiguration(path string) *Configuration {
+ file, err := os.Open(path)
+ if err != nil {
+ log.Fatal("ERROR: Error opening config file. Please provide on with -config")
+ os.Exit(-1)
+ }
+
+ decoder := json.NewDecoder(file)
+ conf := &Configuration{}
+ err = decoder.Decode(conf)
+ if err != nil {
+ log.Fatal("ERROR: Error parsing config file.", err)
+ os.Exit(-1)
+ }
+
+ return conf
+}
+
+func GenConfig(path string) {
+ if path == "" {
+ path = "config.json"
+ }
+ wd, err := os.Getwd()
+ if err != nil {
+ wd = "."
+ }
+ Conf := Configuration{}
+ Conf.TemplateDir = wd + "/templates"
+ Conf.Port = 80
+ Conf.PortSSL = 443
+ Conf.SSL = true
+ Conf.DHParam = "/etc/ssl/certs/dhparam.pem"
+ Conf.SPDY = "spdy"
+ Conf.Root = "/var/www/"
+ Conf.ServerName = []string{"example.org", "*.example.org"}
+ Conf.Index = []string{"index.php", "index.html", "index.htm"}
+ Conf.AccessLog = "/var/log/nginx/" + Conf.ServerName[0] + "/access.log"
+ Conf.ErrorLog = "/var/log/nginx/" + Conf.ServerName[0] + "/error.log"
+ Conf.SSL_Cert = "/etc/ssl/certs/ssl-cert-snakeoil.pem"
+ Conf.SSL_Cert_Key = "/etc/ssl/private/ssl-cert-snakeoil.key"
+ Conf.UsePHP = true
+ Conf.PHP_TCP = false
+ Conf.Robots = true
+ Conf.RobotsDisallow = []string{"/"}
+ Conf.RobotsAllow = nil
+ Conf.Cache_Static = true
+ Conf.Pagespeed = true
+ Conf.UpstreamName = ""
+ Conf.Upstream = []string{"127.0.0.1:8080", "127.0.0.1:8081 backup"}
+
+ file, err := json.MarshalIndent(&Conf, "", " ")
+ if err != nil {
+ log.Fatal("ERROR: Error parsing json.", err)
+ }
+
+ err = ioutil.WriteFile(path, file, 0644)
+ if err != nil {
+ log.Fatal("ERROR: Writing file to "+path, err)
+ }
+
+ fmt.Println("INFO: Generated new config file (" + path + ").")
+}
diff --git a/generate/include.go b/generate/include.go
new file mode 100644
index 0000000..54c2ba9
--- /dev/null
+++ b/generate/include.go
@@ -0,0 +1,30 @@
+package main
+
+import (
+ "io"
+ "io/ioutil"
+ "os"
+ "strings"
+)
+
+// Reads all .txt files in the current folder
+// and encodes them as strings literals in textfiles.go
+func main() {
+ fs, _ := ioutil.ReadDir("templates/")
+ out, _ := os.Create("templates.go")
+ out.Write([]byte("package main \n\nconst (\n"))
+ for _, f := range fs {
+ if strings.HasSuffix(f.Name(), ".tmpl") {
+ out.Write([]byte(strings.TrimSuffix(f.Name(), ".tmpl") + " = `"))
+ f, _ := os.Open("templates/" + f.Name())
+ io.Copy(out, f)
+ out.Write([]byte("`\n"))
+ }
+ }
+ out.Write([]byte(")\n"))
+ out.Write([]byte("func getTemplate() string {\n"))
+ out.Write([]byte(`return "{{define \"block_facebook.tmpl\"}}" + block_facebook + "{{end}}{{define \"cache_static.tmpl\"}}" + cache_static + "{{end}} {{define \"pagespeed.tmpl\"}}" + pagespeed + "{{end}} {{define \"robots.tmpl\"}}" + robots + "{{end}} {{define \"ssl.tmpl\"}}" + ssl + "{{end}}" + server`))
+ out.Write([]byte("\n\n}\n"))
+ out.Write([]byte("func isGenerated() bool { return true }\n"))
+
+}
diff --git a/main.go b/main.go
new file mode 100644
index 0000000..26c0795
--- /dev/null
+++ b/main.go
@@ -0,0 +1,35 @@
+package main
+
+import (
+ "flag"
+ "log"
+ "os"
+ "text/template"
+)
+
+//go:generate go run generate/include.go
+
+func main() {
+ conf_f := flag.String("config", "config.json", "Path to the configuration file.")
+ genConf_f := flag.Bool("genconfig", false, "Generate new configuration file and exit.")
+ flag.Parse()
+
+ if *genConf_f {
+ GenConfig(*conf_f)
+ return
+ }
+
+ Conf = NewConfiguration(*conf_f)
+ var err error
+
+ if isGenerated() {
+ tmpl := template.Must(template.New("ngxconf").Parse(getTemplate()))
+ err = tmpl.Execute(os.Stdout, Conf)
+ } else {
+ tmpl := template.Must(template.New("ngxconf").ParseGlob(Conf.TemplateDir + "/*.tmpl"))
+ err = tmpl.ExecuteTemplate(os.Stdout, "server.tmpl", Conf)
+ }
+ if err != nil {
+ log.Fatal(err)
+ }
+}
diff --git a/templates.go b/templates.go
new file mode 100644
index 0000000..0c47e14
--- /dev/null
+++ b/templates.go
@@ -0,0 +1,4 @@
+package main
+// To be replaced by go generate
+func isGenerated() bool { return false }
+func getTemplate() string { return "" }
diff --git a/templates/block_facebook.tmpl b/templates/block_facebook.tmpl
new file mode 100644
index 0000000..c308cb2
--- /dev/null
+++ b/templates/block_facebook.tmpl
@@ -0,0 +1,3 @@
+if ($http_user_agent ~* facebook) {
+ return 403;
+ }
diff --git a/templates/cache_static.tmpl b/templates/cache_static.tmpl
new file mode 100644
index 0000000..e194ada
--- /dev/null
+++ b/templates/cache_static.tmpl
@@ -0,0 +1,3 @@
+location ~* \.(jpe?g|png|gif|css|js|swf|txt|ico)$ {
+ expires 170h;
+ }
diff --git a/templates/pagespeed.tmpl b/templates/pagespeed.tmpl
new file mode 100644
index 0000000..e1afb8d
--- /dev/null
+++ b/templates/pagespeed.tmpl
@@ -0,0 +1,13 @@
+pagespeed on;
+ pagespeed FileCachePath /var/cache/nginx/pagespeed;
+ location ~ "\.pagespeed\.([a-z]\.)?[a-z]{2}\.[^.]{10}\.[^.]+" {
+ add_header "" "";
+ }
+ location ~ "^/pagespeed_static/" { }
+ location ~ "^/ngx_pagespeed_beacon$" { }
+ pagespeed FileCacheSizeKb 102400;
+ pagespeed FileCacheCleanIntervalMs 3600000;
+ pagespeed FileCacheInodeLimit 500000;
+ pagespeed Statistics on;
+ pagespeed StatisticsLogging on;
+ pagespeed LogDir /var/log/nginx/pagespeed;
diff --git a/templates/robots.tmpl b/templates/robots.tmpl
new file mode 100644
index 0000000..cea822a
--- /dev/null
+++ b/templates/robots.tmpl
@@ -0,0 +1,7 @@
+location = /robots.txt {
+ return 200 "User-agent: *
+ {{if .RobotsDisallow}}{{range .RobotsDisallow}}Disallow: {{.}}
+ {{end}}{{end}}
+ {{if .RobotsAllow}}{{range .RobotsAllow}}Allow: {{.}}
+ {{end}}{{end}}";
+ }
diff --git a/templates/server.tmpl b/templates/server.tmpl
new file mode 100644
index 0000000..38641b5
--- /dev/null
+++ b/templates/server.tmpl
@@ -0,0 +1,43 @@
+{{if .UpstreamName}}upstream {{.UpstreamName}} {
+ {{range .Upstream}}server {{.}};
+ {{end}}
+}
+{{end}}
+server {
+ listen {{.Port}};
+ {{if .SSL}}listen {{.PortSSL}} ssl {{.SPDY}};{{end}}
+ root {{.Root}};
+
+ server_name {{range .ServerName}}{{.}} {{end}};
+ index {{range .Index}}{{.}} {{end}};
+
+ {{if .AccessLog}}access_log {{.AccessLog}};{{end}}
+ {{if .ErrorLog}}error_log {{.ErrorLog}};{{end}}
+
+ # Settings for TLS
+ {{if .SSL}}ssl_certificate {{.SSL_Cert}};
+ ssl_certificate_key {{.SSL_Cert_Key}};
+ {{template "ssl.tmpl" .}}{{else}}# Empty{{end}}
+
+ # Basic PHP configuration
+ {{if .UsePHP}}location ~ \.php$ {
+ include snippets/fastcgi-php.conf;
+ {{if not .PHP_TCP}}fastcgi_pass unix:/var/run/php5-fpm.sock;{{end}}
+ }{{else}}# Empty{{end}}
+
+ # Disallow crawlers
+ {{if .Robots}}{{template "robots.tmpl" .}}{{else}}# Empty{{end}}
+
+ # Cache static content
+ {{if .Cache_Static}}{{template "cache_static.tmpl" .}}{{else}}# Empty{{end}}
+
+ # Google Pagespeed settings
+ {{if .Pagespeed}}{{template "pagespeed.tmpl" .}}{{else}}# Empty{{end}}
+
+ # Disallow Facebook to crawl your sites
+ {{if .Block_Facebook}}{{template "block_facebook.tmpl" .}}{{else}}# Empty{{end}}
+
+ location / {
+ try_files $uri $uri/{{if .UsePHP}} /index.php?$args{{end}};
+ }
+}
diff --git a/templates/ssl.tmpl b/templates/ssl.tmpl
new file mode 100644
index 0000000..2729c09
--- /dev/null
+++ b/templates/ssl.tmpl
@@ -0,0 +1,8 @@
+ssl_prefer_server_ciphers On;
+ ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
+ ssl_ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS;
+ add_header Strict-Transport-Security max-age=15768000;
+ ssl_session_cache shared:SSL:50m;
+ ssl_session_timeout 10m;
+ ssl_dhparam {{.DHParam}};
+ ssl_buffer_size 1400;