ソースを参照

new format for listener section

tags/v1.2.0-rc1
Shivaram Lingamneni 5年前
コミット
eee0747e5e
4個のファイルの変更155行の追加84行の削除
  1. 78
    36
      irc/config.go
  2. 8
    4
      irc/server.go
  3. 44
    20
      oragono.go
  4. 25
    24
      oragono.yaml

+ 78
- 36
irc/config.go ファイルの表示

@@ -41,6 +41,12 @@ type TLSListenConfig struct {
41 41
 	Key  string
42 42
 }
43 43
 
44
+// This is the YAML-deserializable type of the value of the `Server.Listeners` map
45
+type listenerConfigBlock struct {
46
+	TLS TLSListenConfig
47
+	Tor bool
48
+}
49
+
44 50
 // listenerConfig is the config governing a particular listener (bound address),
45 51
 // in particular whether it has TLS or Tor (or both) enabled.
46 52
 type listenerConfig struct {
@@ -252,8 +258,8 @@ type FakelagConfig struct {
252 258
 }
253 259
 
254 260
 type TorListenersConfig struct {
255
-	Listeners                 []string
256
-	RequireSasl               bool `yaml:"require-sasl"`
261
+	Listeners                 []string // legacy only
262
+	RequireSasl               bool     `yaml:"require-sasl"`
257 263
 	Vhost                     string
258 264
 	MaxConnections            int           `yaml:"max-connections"`
259 265
 	ThrottleDuration          time.Duration `yaml:"throttle-duration"`
@@ -267,15 +273,19 @@ type Config struct {
267 273
 	}
268 274
 
269 275
 	Server struct {
270
-		Password             string
271
-		passwordBytes        []byte
272
-		Name                 string
273
-		nameCasefolded       string
274
-		Listen               []string
275
-		UnixBindMode         os.FileMode                `yaml:"unix-bind-mode"`
276
-		TLSListeners         map[string]TLSListenConfig `yaml:"tls-listeners"`
277
-		TorListeners         TorListenersConfig         `yaml:"tor-listeners"`
278
-		listeners            map[string]listenerConfig
276
+		Password       string
277
+		passwordBytes  []byte
278
+		Name           string
279
+		nameCasefolded string
280
+		// Listeners is the new style for configuring listeners:
281
+		Listeners    map[string]listenerConfigBlock
282
+		UnixBindMode os.FileMode        `yaml:"unix-bind-mode"`
283
+		TorListeners TorListenersConfig `yaml:"tor-listeners"`
284
+		// Listen and TLSListeners are the legacy style:
285
+		Listen       []string
286
+		TLSListeners map[string]TLSListenConfig `yaml:"tls-listeners"`
287
+		// either way, the result is this:
288
+		trueListeners        map[string]listenerConfig
279 289
 		STS                  STSConfig
280 290
 		CheckIdent           bool `yaml:"check-ident"`
281 291
 		MOTD                 string
@@ -481,37 +491,63 @@ func (conf *Config) Operators(oc map[string]*OperClass) (map[string]*Oper, error
481 491
 	return operators, nil
482 492
 }
483 493
 
484
-// prepareListeners populates Config.Server.listeners
485
-func (conf *Config) prepareListeners() (err error) {
486
-	torListeners := make(map[string]bool, len(conf.Server.TorListeners.Listeners))
487
-	for _, addr := range conf.Server.TorListeners.Listeners {
488
-		torListeners[addr] = true
494
+func loadTlsConfig(config TLSListenConfig) (tlsConfig *tls.Config, err error) {
495
+	cert, err := tls.LoadX509KeyPair(config.Cert, config.Key)
496
+	if err != nil {
497
+		return nil, ErrInvalidCertKeyPair
489 498
 	}
499
+	result := tls.Config{
500
+		Certificates: []tls.Certificate{cert},
501
+		ClientAuth:   tls.RequestClientCert,
502
+	}
503
+	return &result, nil
504
+}
490 505
 
491
-	conf.Server.listeners = make(map[string]listenerConfig, len(conf.Server.Listen))
492
-
493
-	for _, addr := range conf.Server.Listen {
494
-		var lconf listenerConfig
495
-		lconf.IsTor = torListeners[addr]
496
-		tlsListenConf, ok := conf.Server.TLSListeners[addr]
497
-		if ok {
498
-			cert, err := tls.LoadX509KeyPair(tlsListenConf.Cert, tlsListenConf.Key)
499
-			if err != nil {
500
-				return ErrInvalidCertKeyPair
506
+// prepareListeners populates Config.Server.trueListeners
507
+func (conf *Config) prepareListeners() (err error) {
508
+	listeners := make(map[string]listenerConfig)
509
+	if 0 < len(conf.Server.Listeners) {
510
+		for addr, block := range conf.Server.Listeners {
511
+			var lconf listenerConfig
512
+			lconf.IsTor = block.Tor
513
+			if block.TLS.Cert != "" {
514
+				tlsConfig, err := loadTlsConfig(block.TLS)
515
+				if err != nil {
516
+					return err
517
+				}
518
+				lconf.TLSConfig = tlsConfig
501 519
 			}
502
-			tlsConfig := tls.Config{
503
-				Certificates: []tls.Certificate{cert},
504
-				ClientAuth:   tls.RequestClientCert,
520
+			listeners[addr] = lconf
521
+		}
522
+	} else if 0 < len(conf.Server.Listen) {
523
+		log.Printf("WARNING: configuring listeners via the legacy `server.listen` config option")
524
+		log.Printf("This will be removed in a later release: you should update to use `server.listeners`")
525
+		torListeners := make(map[string]bool, len(conf.Server.TorListeners.Listeners))
526
+		for _, addr := range conf.Server.TorListeners.Listeners {
527
+			torListeners[addr] = true
528
+		}
529
+		for _, addr := range conf.Server.Listen {
530
+			var lconf listenerConfig
531
+			lconf.IsTor = torListeners[addr]
532
+			tlsListenConf, ok := conf.Server.TLSListeners[addr]
533
+			if ok {
534
+				tlsConfig, err := loadTlsConfig(tlsListenConf)
535
+				if err != nil {
536
+					return err
537
+				}
538
+				lconf.TLSConfig = tlsConfig
505 539
 			}
506
-			lconf.TLSConfig = &tlsConfig
540
+			listeners[addr] = lconf
507 541
 		}
508
-		conf.Server.listeners[addr] = lconf
542
+	} else {
543
+		return fmt.Errorf("No listeners were configured")
509 544
 	}
545
+	conf.Server.trueListeners = listeners
510 546
 	return nil
511 547
 }
512 548
 
513
-// LoadConfig loads the given YAML configuration file.
514
-func LoadConfig(filename string) (config *Config, err error) {
549
+// LoadRawConfig loads the config without doing any consistency checks or postprocessing
550
+func LoadRawConfig(filename string) (config *Config, err error) {
515 551
 	data, err := ioutil.ReadFile(filename)
516 552
 	if err != nil {
517 553
 		return nil, err
@@ -521,6 +557,15 @@ func LoadConfig(filename string) (config *Config, err error) {
521 557
 	if err != nil {
522 558
 		return nil, err
523 559
 	}
560
+	return
561
+}
562
+
563
+// LoadConfig loads the given YAML configuration file.
564
+func LoadConfig(filename string) (config *Config, err error) {
565
+	config, err = LoadRawConfig(filename)
566
+	if err != nil {
567
+		return nil, err
568
+	}
524 569
 
525 570
 	config.Filename = filename
526 571
 
@@ -536,9 +581,6 @@ func LoadConfig(filename string) (config *Config, err error) {
536 581
 	if config.Datastore.Path == "" {
537 582
 		return nil, ErrDatastorePathMissing
538 583
 	}
539
-	if len(config.Server.Listen) == 0 {
540
-		return nil, ErrNoListenersDefined
541
-	}
542 584
 	//dan: automagically fix identlen until a few releases in the future (from now, 0.12.0), being a newly-introduced limit
543 585
 	if config.Limits.IdentLen < 1 {
544 586
 		config.Limits.IdentLen = 20

+ 8
- 4
irc/server.go ファイルの表示

@@ -865,7 +865,7 @@ func (server *Server) setupListeners(config *Config) (err error) {
865 865
 	// update or destroy all existing listeners
866 866
 	for addr := range server.listeners {
867 867
 		currentListener := server.listeners[addr]
868
-		newConfig, stillConfigured := config.Server.listeners[addr]
868
+		newConfig, stillConfigured := config.Server.trueListeners[addr]
869 869
 
870 870
 		currentListener.Lock()
871 871
 		currentListener.shouldStop = !stillConfigured
@@ -883,7 +883,11 @@ func (server *Server) setupListeners(config *Config) (err error) {
883 883
 	}
884 884
 
885 885
 	// create new listeners that were not previously configured
886
-	for newAddr, newConfig := range config.Server.listeners {
886
+	numTlsListeners := 0
887
+	for newAddr, newConfig := range config.Server.trueListeners {
888
+		if newConfig.TLSConfig != nil {
889
+			numTlsListeners += 1
890
+		}
887 891
 		_, exists := server.listeners[newAddr]
888 892
 		if !exists {
889 893
 			// make new listener
@@ -898,11 +902,11 @@ func (server *Server) setupListeners(config *Config) (err error) {
898 902
 		}
899 903
 	}
900 904
 
901
-	if len(config.Server.TLSListeners) == 0 {
905
+	if numTlsListeners == 0 {
902 906
 		server.logger.Warning("server", "You are not exposing an SSL/TLS listening port. You should expose at least one port (typically 6697) to accept TLS connections")
903 907
 	}
904 908
 
905
-	if config.Server.listeners[":6697"].TLSConfig == nil {
909
+	if config.Server.trueListeners[":6697"].TLSConfig == nil {
906 910
 		server.logger.Warning("server", "Port 6697 is the standard TLS port for IRC. You should (also) expose port 6697 as a TLS port to ensure clients can connect securely")
907 911
 	}
908 912
 

+ 44
- 20
oragono.go ファイルの表示

@@ -39,6 +39,46 @@ func getPassword() string {
39 39
 	return strings.TrimSpace(text)
40 40
 }
41 41
 
42
+// implements the `oragono mkcerts` command
43
+func doMkcerts(configFile string, quiet bool) {
44
+	config, err := irc.LoadRawConfig(configFile)
45
+	if err != nil {
46
+		log.Fatal(err)
47
+	}
48
+	if !quiet {
49
+		log.Println("making self-signed certificates")
50
+	}
51
+
52
+	certToKey := make(map[string]string)
53
+	for name, conf := range config.Server.Listeners {
54
+		if conf.TLS.Cert == "" {
55
+			continue
56
+		}
57
+		existingKey, ok := certToKey[conf.TLS.Cert]
58
+		if ok {
59
+			if existingKey == conf.TLS.Key {
60
+				continue
61
+			} else {
62
+				log.Fatal("Conflicting TLS key files for", conf.TLS.Cert)
63
+			}
64
+		}
65
+		if !quiet {
66
+			log.Printf(" making cert for %s listener\n", name)
67
+		}
68
+		host := config.Server.Name
69
+		cert, key := conf.TLS.Cert, conf.TLS.Key
70
+		err := mkcerts.CreateCert("Oragono", host, cert, key)
71
+		if err == nil {
72
+			if !quiet {
73
+				log.Printf("  Certificate created at %s : %s\n", cert, key)
74
+			}
75
+			certToKey[cert] = key
76
+		} else {
77
+			log.Fatal("  Could not create certificate:", err.Error())
78
+		}
79
+	}
80
+}
81
+
42 82
 func main() {
43 83
 	version := irc.SemVer
44 84
 	usage := `oragono.
@@ -88,11 +128,14 @@ Options:
88 128
 	} else if arguments["mksecret"].(bool) {
89 129
 		fmt.Println(utils.GenerateSecretKey())
90 130
 		return
131
+	} else if arguments["mkcerts"].(bool) {
132
+		doMkcerts(arguments["--conf"].(string), arguments["--quiet"].(bool))
133
+		return
91 134
 	}
92 135
 
93 136
 	configfile := arguments["--conf"].(string)
94 137
 	config, err := irc.LoadConfig(configfile)
95
-	if err != nil {
138
+	if err != nil && !(err == irc.ErrInvalidCertKeyPair && arguments["mkcerts"].(bool)) {
96 139
 		log.Fatal("Config file did not load successfully: ", err.Error())
97 140
 	}
98 141
 
@@ -114,25 +157,6 @@ Options:
114 157
 		if !arguments["--quiet"].(bool) {
115 158
 			log.Println("database upgraded: ", config.Datastore.Path)
116 159
 		}
117
-	} else if arguments["mkcerts"].(bool) {
118
-		if !arguments["--quiet"].(bool) {
119
-			log.Println("making self-signed certificates")
120
-		}
121
-
122
-		for name, conf := range config.Server.TLSListeners {
123
-			if !arguments["--quiet"].(bool) {
124
-				log.Printf(" making cert for %s listener\n", name)
125
-			}
126
-			host := config.Server.Name
127
-			err := mkcerts.CreateCert("Oragono", host, conf.Cert, conf.Key)
128
-			if err == nil {
129
-				if !arguments["--quiet"].(bool) {
130
-					log.Printf("  Certificate created at %s : %s\n", conf.Cert, conf.Key)
131
-				}
132
-			} else {
133
-				log.Fatal("  Could not create certificate:", err.Error())
134
-			}
135
-		}
136 160
 	} else if arguments["run"].(bool) {
137 161
 		if !arguments["--quiet"].(bool) {
138 162
 			logman.Info("server", fmt.Sprintf("Oragono v%s starting", irc.SemVer))

+ 25
- 24
oragono.yaml ファイルの表示

@@ -11,14 +11,30 @@ server:
11 11
     name: oragono.test
12 12
 
13 13
     # addresses to listen on
14
-    listen:
15
-        - ":6697" # SSL/TLS port
16
-        - ":6667" # plaintext port
17
-        # To disable plaintext over the Internet, comment out :6667 and replace with:
18
-        # - "127.0.0.1:6667" # (loopback ipv4, localhost-only)
19
-        # - "[::1]:6667"     # (loopback ipv6, localhost-only)
20
-        # Unix domain socket for proxying:
21
-        # - "/tmp/oragono_sock"
14
+    listeners:
15
+        # This is the standard SSL/TLS port for IRC:
16
+        ":6697":
17
+            tls:
18
+                key: tls.key
19
+                cert: tls.crt
20
+
21
+        # The standard plaintext port for IRC is 6667. Since using plaintext over
22
+        # the public Internet poses security and privacy issues, we recommend using
23
+        # plaintext only on local interfaces:
24
+        "127.0.0.1:6667": # (loopback ipv4, localhost-only)
25
+        "[::1]:6667":     # (loopback ipv6, localhost-only)
26
+        # If you need to use plaintext on non-local interfaces, comment out the above
27
+        # two lines, then uncomment the following line:
28
+        # ":6667":
29
+
30
+        # Example of a Unix domain socket for proxying:
31
+        # "/tmp/oragono_sock":
32
+
33
+        # Example of a Tor listener: any connection that comes in on this listener will
34
+        # be considered a Tor connection. It is strongly recommended that this listener
35
+        # *not* be on a public interface --- it should be on 127.0.0.0/8 or unix domain:
36
+        # "/tmp/oragono_tor_sock":
37
+        #     tor: true
22 38
 
23 39
     # sets the permissions for Unix listen sockets. on a typical Linux system,
24 40
     # the default is 0775 or 0755, which prevents other users/groups from connecting
@@ -26,23 +42,8 @@ server:
26 42
     # where anyone can connect.
27 43
     unix-bind-mode: 0777
28 44
 
29
-    # tls listeners
30
-    tls-listeners:
31
-        # listener on ":6697"
32
-        ":6697":
33
-            key: tls.key
34
-            cert: tls.crt
35
-
36
-    # tor listeners: designate listeners for use by a tor hidden service / .onion address
37
-    # WARNING: if you are running oragono as a pure hidden service, see the
38
-    # anonymization / hardening recommendations in docs/MANUAL.md
45
+    # configure the behavior of Tor listeners (ignored if you didn't enable any):
39 46
     tor-listeners:
40
-        # any connections that come in on these listeners will be considered
41
-        # Tor connections. it is strongly recommended that these listeners *not*
42
-        # be on public interfaces: they should be on 127.0.0.0/8 or unix domain
43
-        listeners:
44
-        #    - "/tmp/oragono_tor_sock"
45
-
46 47
         # if this is true, connections from Tor must authenticate with SASL
47 48
         require-sasl: false
48 49
 

読み込み中…
キャンセル
保存