3
0
mirror of https://github.com/ergochat/ergo.git synced 2024-11-22 11:59:40 +01:00

Add native SSL/TLS listener support from @enmand for our new config

This commit is contained in:
Daniel Oaks 2016-04-13 20:45:09 +10:00
parent 8dc2732137
commit c3288823af
5 changed files with 57 additions and 9 deletions

1
.gitignore vendored
View File

@ -1 +1,2 @@
/ircd.* /ircd.*
/ssl.*

View File

@ -11,14 +11,13 @@ Oragono is a very early, extremely experimental fork of the [Ergonomadic](https:
* channels that [persist][go-sqlite] between restarts (+P) * channels that [persist][go-sqlite] between restarts (+P)
* messages are queued in the same order to all connected clients * messages are queued in the same order to all connected clients
# What about SSL/TLS support? # What about SSL/TLS?
Go has a not-yet-verified-as-safe TLS 1.2 implementation. Sadly, many popular There is inbuilt TLS support using the Go TLS implementation. However,
IRC clients will negotiate nothing newer than SSLv2. If you want to use SSL to
protect traffic, I recommend using
[stunnel](https://www.stunnel.org/index.html) version 4.56 with haproxy's [stunnel](https://www.stunnel.org/index.html) version 4.56 with haproxy's
[PROXY protocol][proxy-proto]. This will allow the server to get the client's [PROXY protocol](http://haproxy.1wt.eu/download/1.5/doc/proxy-protocol.txt)
original addresses for hostname lookups. may also be used. This will allow the server to get the client's original
addresses for hostname lookups.
# Installation # Installation

View File

@ -1,6 +1,7 @@
package irc package irc
import ( import (
"crypto/tls"
"errors" "errors"
"io/ioutil" "io/ioutil"
"log" "log"
@ -12,6 +13,24 @@ type PassConfig struct {
Password string Password string
} }
// SSLListenConfig defines configuration options for listening on SSL
type SSLListenConfig struct {
Cert string
Key string
}
// Certificate returns the SSL certificate assicated with this SSLListenConfig
func (conf *SSLListenConfig) Config() (*tls.Config, error) {
cert, err := tls.LoadX509KeyPair(conf.Cert, conf.Key)
if err != nil {
return nil, errors.New("ssl cert+key: invalid pair")
}
return &tls.Config{
Certificates: []tls.Certificate{cert},
}, err
}
func (conf *PassConfig) PasswordBytes() []byte { func (conf *PassConfig) PasswordBytes() []byte {
bytes, err := DecodePassword(conf.Password) bytes, err := DecodePassword(conf.Password)
if err != nil { if err != nil {
@ -35,6 +54,8 @@ type Config struct {
MOTD string MOTD string
} }
SSLListener map[string]*SSLListenConfig
Operator map[string]*PassConfig Operator map[string]*PassConfig
Theater map[string]*PassConfig Theater map[string]*PassConfig
@ -60,6 +81,18 @@ func (conf *Config) Theaters() map[Name][]byte {
return theaters return theaters
} }
func (conf *Config) SSLListeners() map[Name]*tls.Config {
sslListeners := make(map[Name]*tls.Config)
for s, sslListenersConf := range conf.SSLListener {
config, err := sslListenersConf.Config()
if err != nil {
log.Fatal(err)
}
sslListeners[NewName(s)] = config
}
return sslListeners
}
func LoadConfig(filename string) (config *Config, err error) { func LoadConfig(filename string) (config *Config, err error) {
data, err := ioutil.ReadFile(filename) data, err := ioutil.ReadFile(filename)
if err != nil { if err != nil {

View File

@ -2,6 +2,7 @@ package irc
import ( import (
"bufio" "bufio"
"crypto/tls"
"database/sql" "database/sql"
"fmt" "fmt"
"log" "log"
@ -88,7 +89,7 @@ func NewServer(config *Config) *Server {
server.loadChannels() server.loadChannels()
for _, addr := range config.Server.Listen { for _, addr := range config.Server.Listen {
server.listen(addr) server.listen(addr, config.SSLListeners())
} }
if config.Server.Wslisten != "" { if config.Server.Wslisten != "" {
@ -223,13 +224,18 @@ func (server *Server) Run() {
// listen goroutine // listen goroutine
// //
func (s *Server) listen(addr string) { func (s *Server) listen(addr string, ssl map[Name]*tls.Config) {
config, listenSSL := ssl[NewName(addr)]
listener, err := net.Listen("tcp", addr) listener, err := net.Listen("tcp", addr)
if err != nil { if err != nil {
log.Fatal(s, "listen error: ", err) log.Fatal(s, "listen error: ", err)
} }
Log.info.Printf("%s listening on %s", s, addr) if listenSSL {
listener = tls.NewListener(listener, config)
}
Log.info.Printf("%s listening on %s. ssl: %t", s, addr, listenSSL)
go func() { go func() {
for { for {
@ -250,6 +256,7 @@ func (s *Server) listen(addr string) {
// //
func (s *Server) wslisten(addr string) { func (s *Server) wslisten(addr string) {
//TODO(dan): open a https websocket here if ssl/tls details are setup in the config for the wslistener
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
if r.Method != "GET" { if r.Method != "GET" {
Log.error.Printf("%s method not allowed", s) Log.error.Printf("%s method not allowed", s)

View File

@ -18,6 +18,7 @@ server:
- ":6667" - ":6667"
- "127.0.0.1:6668" - "127.0.0.1:6668"
- "[::1]:6668" - "[::1]:6668"
- ":6697" # ssl port
# websocket listening port # websocket listening port
wslisten: ":8080" wslisten: ":8080"
@ -33,6 +34,13 @@ server:
# if you change the motd, you should move it to ircd.motd # if you change the motd, you should move it to ircd.motd
motd: oragono.motd motd: oragono.motd
# ssl listeners
ssllistener:
# listener on ":6697"
":6697":
key: ssl.key
cert: ssl.crt
# ircd operators # ircd operators
operator: operator:
# operator named 'dan' # operator named 'dan'