diff options
| author | horus_arch | 2015-07-27 22:24:09 +0200 |
|---|---|---|
| committer | horus_arch | 2015-07-27 22:52:09 +0200 |
| commit | ebfb0155ac6a4fba93ebb846878ca211e9384226 (patch) | |
| tree | 0f9faa9e9afed9ce92dbd8e5cac796a833f86cd5 | |
| download | ngxconf-ebfb0155ac6a4fba93ebb846878ca211e9384226.tar.gz | |
| -rw-r--r-- | Makefile | 48 | ||||
| -rw-r--r-- | config.go | 100 | ||||
| -rw-r--r-- | generate/include.go | 30 | ||||
| -rw-r--r-- | main.go | 35 | ||||
| -rw-r--r-- | templates.go | 4 | ||||
| -rw-r--r-- | templates/block_facebook.tmpl | 3 | ||||
| -rw-r--r-- | templates/cache_static.tmpl | 3 | ||||
| -rw-r--r-- | templates/pagespeed.tmpl | 13 | ||||
| -rw-r--r-- | templates/robots.tmpl | 7 | ||||
| -rw-r--r-- | templates/server.tmpl | 43 | ||||
| -rw-r--r-- | templates/ssl.tmpl | 8 |
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")) + +} @@ -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; |
