Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,16 @@ These depend on which features you want to use and on whether you use homer5 or

![image](https://user-images.githubusercontent.com/20154956/54483281-ef3f5700-4850-11e9-8da1-9b8bed6186e3.png)

#### HEP input listeners
Configure the bind address for each listener in your config (flags/env/file/web):

* `HEPAddr` - UDP HEP listener (default `0.0.0.0:9060`)
* `HEPTCPAddr` - TCP HEP listener (disabled when empty)
* `HEPTLSAddr` - TLS HEP listener (disabled when empty)
* `HEPWSAddr` - WebSocket HEP listener (disabled when empty)

When enabling TLS, also set `TLSCertFile` and `TLSKeyFile` (and optional `TLSClientCAFile`, `TLSRequireClientCert`, `TLSMinVersion`) in the same configuration source.

Comment thread
adubovikov marked this conversation as resolved.
To set up a systemd service, use the sample [service file](https://github.com/sipcapture/heplify-server/blob/master/example/)
and follow the instructions found at the top of the file.

Expand Down
7 changes: 5 additions & 2 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,9 @@ type HeplifyServer struct {
ScriptEngine string `default:"lua"`
ScriptFolder string `default:""`
ScriptHEPFilter []int `default:"1,5,100"`
TLSCertFolder string `default:"."`
TLSMinVersion string `default:"1.2"`
TLSCertFile string `default:""`
TLSKeyFile string `default:""`
TLSClientCAFile string `default:""`
TLSRequireClientCert bool `default:"false"`
TLSMinVersion string `default:"1.2"`
Comment on lines +83 to +87

Copilot AI Mar 10, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change removes TLSCertFolder (and the previous auto-generated certificate behavior) in favor of explicit TLSCertFile/TLSKeyFile. That’s a breaking configuration change for existing deployments; consider keeping TLSCertFolder as a deprecated fallback (or adding a clear migration note in docs/release notes) so existing configs don’t silently stop working when HEPTLSAddr is enabled.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot apply changes based on this feedback

}
1 change: 0 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ require (
github.com/golang/snappy v0.0.4
github.com/lib/pq v1.10.9
github.com/mailru/easyjson v0.7.1 // indirect
github.com/negbie/cert v0.0.0-20190324145947-d1018a8fb00f
github.com/negbie/logp v0.0.0-20190313141056-04cebff7f846
github.com/negbie/multiconfig v1.0.0
github.com/olivere/elastic v6.2.33+incompatible
Expand Down
2 changes: 0 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -878,8 +878,6 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/negbie/cert v0.0.0-20190324145947-d1018a8fb00f h1:M55iH2PERd3rI05upU5PUVeKIRHaNkjJgFtrIE0G2gU=
github.com/negbie/cert v0.0.0-20190324145947-d1018a8fb00f/go.mod h1:gu8czYryxJq/ecHYWjTXLbVSiAkxUwSNgzfPTrKEJ2k=
github.com/negbie/logp v0.0.0-20190313141056-04cebff7f846 h1:PAr5hcOgvc2m71W4SlbUsAbUnea5lNjB5/DfIHW9f8Q=
github.com/negbie/logp v0.0.0-20190313141056-04cebff7f846/go.mod h1:xTKf9aKLuVL0r9wxWouR+/4ctK2ywm0rTPFY2klrnOg=
github.com/negbie/multiconfig v1.0.0 h1:JXrB+RYMhGS/xlXGJab/4g7AoAIo3tFrwHr8LN3i0fg=
Expand Down
54 changes: 46 additions & 8 deletions server/tls.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@ package input

import (
"crypto/tls"
"crypto/x509"
"fmt"
"net"
"path/filepath"
"os"
"sync"
"sync/atomic"
"time"

"github.com/negbie/cert"
"github.com/negbie/logp"
"github.com/sipcapture/heplify-server/config"
)
Expand Down Expand Up @@ -46,13 +47,11 @@ func (h *HEPInput) serveTLS(addr string) {
return
}

// get path for certificate/key storage
cPath := config.Setting.TLSCertFolder
minTLSVersion := parseTLSVersion(config.Setting.TLSMinVersion)
// load any existing certs, otherwise generate a new one
ca, err := cert.NewCertificateAuthority(filepath.Join(cPath, "heplify-server"))

tlsConfig, err := loadTLSConfig(minTLSVersion)
if err != nil {
logp.Err("%v", err)
logp.Err("TLS configuration error: %v", err)
return
}

Expand Down Expand Up @@ -81,7 +80,7 @@ func (h *HEPInput) serveTLS(addr string) {
logp.Info("new TLS connection %s -> %s", conn.RemoteAddr(), conn.LocalAddr())
wg.Add(1)
go func() {
h.handleTLS(tls.Server(conn, &tls.Config{GetCertificate: ca.GetCertificate, MinVersion: minTLSVersion}))
h.handleTLS(tls.Server(conn, tlsConfig))
wg.Done()
}()
Comment thread
adubovikov marked this conversation as resolved.
}
Expand All @@ -90,3 +89,42 @@ func (h *HEPInput) serveTLS(addr string) {
func (h *HEPInput) handleTLS(c net.Conn) {
h.handleStream(c, "TLS")
}

func loadTLSConfig(minTLSVersion uint16) (*tls.Config, error) {
certFile := config.Setting.TLSCertFile
keyFile := config.Setting.TLSKeyFile
if certFile == "" || keyFile == "" {
return nil, fmt.Errorf("TLSCertFile and TLSKeyFile must be set for TLS termination")
}

cert, err := tls.LoadX509KeyPair(certFile, keyFile)
if err != nil {
return nil, fmt.Errorf("load TLS certificate/key: %w", err)
}

tlsConfig := &tls.Config{
Certificates: []tls.Certificate{cert},
MinVersion: minTLSVersion,
}

if config.Setting.TLSClientCAFile != "" {
caPEM, err := os.ReadFile(config.Setting.TLSClientCAFile)
if err != nil {
return nil, fmt.Errorf("read TLSClientCAFile: %w", err)
}
caPool := x509.NewCertPool()
if ok := caPool.AppendCertsFromPEM(caPEM); !ok {
return nil, fmt.Errorf("TLSClientCAFile did not contain any valid certificates")
}
tlsConfig.ClientCAs = caPool
if config.Setting.TLSRequireClientCert {
tlsConfig.ClientAuth = tls.RequireAndVerifyClientCert
} else {
tlsConfig.ClientAuth = tls.VerifyClientCertIfGiven
}
} else if config.Setting.TLSRequireClientCert {
return nil, fmt.Errorf("TLSClientCAFile must be set when TLSRequireClientCert is enabled")
}

return tlsConfig, nil
Comment thread
adubovikov marked this conversation as resolved.
}
Loading