mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Merge pull request #18998 from calavera/syslog_tls
Allow syslog over TCP+TLS.
This commit is contained in:
commit
656979670c
14 changed files with 719 additions and 9 deletions
|
@ -4,9 +4,9 @@
|
||||||
package syslog
|
package syslog
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/tls"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log/syslog"
|
|
||||||
"net"
|
"net"
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
|
@ -14,13 +14,19 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
syslog "github.com/RackSec/srslog"
|
||||||
|
|
||||||
"github.com/Sirupsen/logrus"
|
"github.com/Sirupsen/logrus"
|
||||||
"github.com/docker/docker/daemon/logger"
|
"github.com/docker/docker/daemon/logger"
|
||||||
"github.com/docker/docker/daemon/logger/loggerutils"
|
"github.com/docker/docker/daemon/logger/loggerutils"
|
||||||
"github.com/docker/docker/pkg/urlutil"
|
"github.com/docker/docker/pkg/urlutil"
|
||||||
|
"github.com/docker/go-connections/tlsconfig"
|
||||||
)
|
)
|
||||||
|
|
||||||
const name = "syslog"
|
const (
|
||||||
|
name = "syslog"
|
||||||
|
secureProto = "tcp+tls"
|
||||||
|
)
|
||||||
|
|
||||||
var facilities = map[string]syslog.Priority{
|
var facilities = map[string]syslog.Priority{
|
||||||
"kern": syslog.LOG_KERN,
|
"kern": syslog.LOG_KERN,
|
||||||
|
@ -77,12 +83,19 @@ func New(ctx logger.Context) (logger.Logger, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
log, err := syslog.Dial(
|
logTag := path.Base(os.Args[0]) + "/" + tag
|
||||||
proto,
|
|
||||||
address,
|
var log *syslog.Writer
|
||||||
facility,
|
if proto == secureProto {
|
||||||
path.Base(os.Args[0])+"/"+tag,
|
tlsConfig, tlsErr := parseTLSConfig(ctx.Config)
|
||||||
)
|
if tlsErr != nil {
|
||||||
|
return nil, tlsErr
|
||||||
|
}
|
||||||
|
log, err = syslog.DialWithTLSConfig(proto, address, facility, logTag, tlsConfig)
|
||||||
|
} else {
|
||||||
|
log, err = syslog.Dial(proto, address, facility, logTag)
|
||||||
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -147,6 +160,10 @@ func ValidateLogOpt(cfg map[string]string) error {
|
||||||
case "syslog-address":
|
case "syslog-address":
|
||||||
case "syslog-facility":
|
case "syslog-facility":
|
||||||
case "syslog-tag":
|
case "syslog-tag":
|
||||||
|
case "syslog-tls-ca-cert":
|
||||||
|
case "syslog-tls-cert":
|
||||||
|
case "syslog-tls-key":
|
||||||
|
case "syslog-tls-skip-verify":
|
||||||
case "tag":
|
case "tag":
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("unknown log opt '%s' for syslog log driver", key)
|
return fmt.Errorf("unknown log opt '%s' for syslog log driver", key)
|
||||||
|
@ -177,3 +194,16 @@ func parseFacility(facility string) (syslog.Priority, error) {
|
||||||
|
|
||||||
return syslog.Priority(0), errors.New("invalid syslog facility")
|
return syslog.Priority(0), errors.New("invalid syslog facility")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func parseTLSConfig(cfg map[string]string) (*tls.Config, error) {
|
||||||
|
_, skipVerify := cfg["syslog-tls-skip-verify"]
|
||||||
|
|
||||||
|
opts := tlsconfig.Options{
|
||||||
|
CAFile: cfg["syslog-tls-ca-cert"],
|
||||||
|
CertFile: cfg["syslog-tls-cert"],
|
||||||
|
KeyFile: cfg["syslog-tls-key"],
|
||||||
|
InsecureSkipVerify: skipVerify,
|
||||||
|
}
|
||||||
|
|
||||||
|
return tlsconfig.Client(opts)
|
||||||
|
}
|
||||||
|
|
|
@ -69,9 +69,13 @@ If `max-size` and `max-file` are set, `docker logs` only returns the log lines f
|
||||||
|
|
||||||
The following logging options are supported for the `syslog` logging driver:
|
The following logging options are supported for the `syslog` logging driver:
|
||||||
|
|
||||||
--log-opt syslog-address=[tcp|udp]://host:port
|
--log-opt syslog-address=[tcp|udp|tcp+tls]://host:port
|
||||||
--log-opt syslog-address=unix://path
|
--log-opt syslog-address=unix://path
|
||||||
--log-opt syslog-facility=daemon
|
--log-opt syslog-facility=daemon
|
||||||
|
--log-opt syslog-tls-ca-cert=/etc/ca-certificates/custom/ca.pem
|
||||||
|
--log-opt syslog-tls-cert=/etc/ca-certificates/custom/cert.pem
|
||||||
|
--log-opt syslog-tls-key=/etc/ca-certificates/custom/key.pem
|
||||||
|
--log-opt syslog-tls-skip-verify=true
|
||||||
--log-opt tag="mailer"
|
--log-opt tag="mailer"
|
||||||
|
|
||||||
`syslog-address` specifies the remote syslog server address where the driver connects to.
|
`syslog-address` specifies the remote syslog server address where the driver connects to.
|
||||||
|
@ -107,6 +111,19 @@ the following named facilities:
|
||||||
* `local6`
|
* `local6`
|
||||||
* `local7`
|
* `local7`
|
||||||
|
|
||||||
|
`syslog-tls-ca-cert` specifies the absolute path to the trust certificates
|
||||||
|
signed by the CA. This option is ignored if the address protocol is not `tcp+tls`.
|
||||||
|
|
||||||
|
`syslog-tls-cert` specifies the absolute path to the TLS certificate file.
|
||||||
|
This option is ignored if the address protocol is not `tcp+tls`.
|
||||||
|
|
||||||
|
`syslog-tls-key` specifies the absolute path to the TLS key file.
|
||||||
|
This option is ignored if the address protocol is not `tcp+tls`.
|
||||||
|
|
||||||
|
`syslog-tls-skip-verify` configures the TLS verification.
|
||||||
|
This verification is enabled by default, but it can be overriden by setting
|
||||||
|
this option to `true`. This option is ignored if the address protocol is not `tcp+tls`.
|
||||||
|
|
||||||
By default, Docker uses the first 12 characters of the container ID to tag log messages.
|
By default, Docker uses the first 12 characters of the container ID to tag log messages.
|
||||||
Refer to the [log tag option documentation](log_tags.md) for customizing
|
Refer to the [log tag option documentation](log_tags.md) for customizing
|
||||||
the log tag format.
|
the log tag format.
|
||||||
|
|
|
@ -23,6 +23,7 @@ clone git golang.org/x/net 47990a1ba55743e6ef1affd3a14e5bac8553615d https://gith
|
||||||
clone git github.com/docker/go-units 651fc226e7441360384da338d0fd37f2440ffbe3
|
clone git github.com/docker/go-units 651fc226e7441360384da338d0fd37f2440ffbe3
|
||||||
clone git github.com/docker/go-connections v0.1.2
|
clone git github.com/docker/go-connections v0.1.2
|
||||||
clone git github.com/docker/engine-api v0.1.3
|
clone git github.com/docker/engine-api v0.1.3
|
||||||
|
clone git github.com/RackSec/srslog 6eb773f331e46fbba8eecb8e794e635e75fc04de
|
||||||
|
|
||||||
#get libnetwork packages
|
#get libnetwork packages
|
||||||
clone git github.com/docker/libnetwork c8ec4bd24e1e76feb4f79e3924c68cd2ce89938a
|
clone git github.com/docker/libnetwork c8ec4bd24e1e76feb4f79e3924c68cd2ce89938a
|
||||||
|
|
1
vendor/src/github.com/RackSec/srslog/.gitignore
vendored
Normal file
1
vendor/src/github.com/RackSec/srslog/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
.cover
|
13
vendor/src/github.com/RackSec/srslog/.travis.yml
vendored
Normal file
13
vendor/src/github.com/RackSec/srslog/.travis.yml
vendored
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
sudo: required
|
||||||
|
dist: trusty
|
||||||
|
group: edge
|
||||||
|
language: go
|
||||||
|
go:
|
||||||
|
- 1.5
|
||||||
|
script:
|
||||||
|
- |
|
||||||
|
go get ./...
|
||||||
|
go test -v ./...
|
||||||
|
notifications:
|
||||||
|
slack:
|
||||||
|
secure: dtDue9gP6CRR1jYjEf6raXXFak3QKGcCFvCf5mfvv5XScdpmc3udwgqc5TdyjC0goaC9OK/4jTcCD30dYZm/u6ux3E9mo3xwMl2xRLHx76p5r9rSQtloH19BDwA2+A+bpDfFQVz05k2YXuTiGSvNMMdwzx+Dr294Sl/z43RFB4+b9/R/6LlFpRW89IwftvpLAFnBy4K/ZcspQzKM+rQfQTL5Kk+iZ/KBsuR/VziDq6MoJ8t43i4ee8vwS06vFBKDbUiZ4FIZpLgc2RAL5qso5aWRKYXL6waXfoKHZWKPe0w4+9IY1rDJxG1jEb7YGgcbLaF9xzPRRs2b2yO/c87FKpkh6PDgYHfLjpgXotCoojZrL4p1x6MI1ldJr3NhARGPxS9r4liB9n6Y5nD+ErXi1IMf55fuUHcPY27Jc0ySeLFeM6cIWJ8OhFejCgGw6a5DnnmJo0PqopsaBDHhadpLejT1+K6bL2iGkT4SLcVNuRGLs+VyuNf1+5XpkWZvy32vquO7SZOngLLBv+GIem+t3fWm0Z9s/0i1uRCQei1iUutlYjoV/LBd35H2rhob4B5phIuJin9kb0zbHf6HnaoN0CtN8r0d8G5CZiInVlG5Xcid5Byb4dddf5U2EJTDuCMVyyiM7tcnfjqw9UbVYNxtYM9SzcqIq+uVqM8pYL9xSec=
|
50
vendor/src/github.com/RackSec/srslog/CODE_OF_CONDUCT.md
vendored
Normal file
50
vendor/src/github.com/RackSec/srslog/CODE_OF_CONDUCT.md
vendored
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
# Contributor Code of Conduct
|
||||||
|
|
||||||
|
As contributors and maintainers of this project, and in the interest of
|
||||||
|
fostering an open and welcoming community, we pledge to respect all people who
|
||||||
|
contribute through reporting issues, posting feature requests, updating
|
||||||
|
documentation, submitting pull requests or patches, and other activities.
|
||||||
|
|
||||||
|
We are committed to making participation in this project a harassment-free
|
||||||
|
experience for everyone, regardless of level of experience, gender, gender
|
||||||
|
identity and expression, sexual orientation, disability, personal appearance,
|
||||||
|
body size, race, ethnicity, age, religion, or nationality.
|
||||||
|
|
||||||
|
Examples of unacceptable behavior by participants include:
|
||||||
|
|
||||||
|
* The use of sexualized language or imagery
|
||||||
|
* Personal attacks
|
||||||
|
* Trolling or insulting/derogatory comments
|
||||||
|
* Public or private harassment
|
||||||
|
* Publishing other's private information, such as physical or electronic
|
||||||
|
addresses, without explicit permission
|
||||||
|
* Other unethical or unprofessional conduct
|
||||||
|
|
||||||
|
Project maintainers have the right and responsibility to remove, edit, or
|
||||||
|
reject comments, commits, code, wiki edits, issues, and other contributions
|
||||||
|
that are not aligned to this Code of Conduct, or to ban temporarily or
|
||||||
|
permanently any contributor for other behaviors that they deem inappropriate,
|
||||||
|
threatening, offensive, or harmful.
|
||||||
|
|
||||||
|
By adopting this Code of Conduct, project maintainers commit themselves to
|
||||||
|
fairly and consistently applying these principles to every aspect of managing
|
||||||
|
this project. Project maintainers who do not follow or enforce the Code of
|
||||||
|
Conduct may be permanently removed from the project team.
|
||||||
|
|
||||||
|
This Code of Conduct applies both within project spaces and in public spaces
|
||||||
|
when an individual is representing the project or its community.
|
||||||
|
|
||||||
|
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||||
|
reported by contacting a project maintainer at [sirsean@gmail.com]. All
|
||||||
|
complaints will be reviewed and investigated and will result in a response that
|
||||||
|
is deemed necessary and appropriate to the circumstances. Maintainers are
|
||||||
|
obligated to maintain confidentiality with regard to the reporter of an
|
||||||
|
incident.
|
||||||
|
|
||||||
|
|
||||||
|
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
|
||||||
|
version 1.3.0, available at
|
||||||
|
[http://contributor-covenant.org/version/1/3/0/][version]
|
||||||
|
|
||||||
|
[homepage]: http://contributor-covenant.org
|
||||||
|
[version]: http://contributor-covenant.org/version/1/3/0/
|
27
vendor/src/github.com/RackSec/srslog/LICENSE
vendored
Normal file
27
vendor/src/github.com/RackSec/srslog/LICENSE
vendored
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
Copyright (c) 2015 Rackspace. All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are
|
||||||
|
met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the following disclaimer
|
||||||
|
in the documentation and/or other materials provided with the
|
||||||
|
distribution.
|
||||||
|
* Neither the name of Google Inc. nor the names of its
|
||||||
|
contributors may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
131
vendor/src/github.com/RackSec/srslog/README.md
vendored
Normal file
131
vendor/src/github.com/RackSec/srslog/README.md
vendored
Normal file
|
@ -0,0 +1,131 @@
|
||||||
|
[![Build Status](https://travis-ci.org/RackSec/srslog.svg?branch=master)](https://travis-ci.org/RackSec/srslog)
|
||||||
|
|
||||||
|
# srslog
|
||||||
|
|
||||||
|
Go has a `syslog` package in the standard library, but it has the following
|
||||||
|
shortcomings:
|
||||||
|
|
||||||
|
1. It doesn't have TLS support
|
||||||
|
2. [According to bradfitz on the Go team, it is no longer being maintained.](https://github.com/golang/go/issues/13449#issuecomment-161204716)
|
||||||
|
|
||||||
|
I agree that it doesn't need to be in the standard library. So, I've
|
||||||
|
followed Brad's suggestion and have made a separate project to handle syslog.
|
||||||
|
|
||||||
|
This code was taken directly from the Go project as a base to start from.
|
||||||
|
|
||||||
|
However, this _does_ have TLS support.
|
||||||
|
|
||||||
|
# Usage
|
||||||
|
|
||||||
|
Basic usage retains the same interface as the original `syslog` package. We
|
||||||
|
only added to the interface where required to support new functionality.
|
||||||
|
|
||||||
|
Switch from the standard library:
|
||||||
|
|
||||||
|
```
|
||||||
|
import(
|
||||||
|
//"log/syslog"
|
||||||
|
syslog "github.com/RackSec/srslog"
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
You can still use it for local syslog:
|
||||||
|
|
||||||
|
```
|
||||||
|
w, err := syslog.Dial("", "", syslog.LOG_ERR, "testtag")
|
||||||
|
```
|
||||||
|
|
||||||
|
Or to unencrypted UDP:
|
||||||
|
|
||||||
|
```
|
||||||
|
w, err := syslog.Dial("udp", "192.168.0.50:514", syslog.LOG_ERR, "testtag")
|
||||||
|
```
|
||||||
|
|
||||||
|
Or to unencrypted TCP:
|
||||||
|
|
||||||
|
```
|
||||||
|
w, err := syslog.Dial("tcp", "192.168.0.51:514", syslog.LOG_ERR, "testtag")
|
||||||
|
```
|
||||||
|
|
||||||
|
But now you can also send messages via TLS-encrypted TCP:
|
||||||
|
|
||||||
|
```
|
||||||
|
w, err := syslog.DialWithTLSCertPath("tcp+tls", "192.168.0.52:514", syslog.LOG_ERR, "testtag", "/path/to/servercert.pem")
|
||||||
|
```
|
||||||
|
|
||||||
|
And if you need more control over your TLS configuration :
|
||||||
|
|
||||||
|
```
|
||||||
|
pool := x509.NewCertPool()
|
||||||
|
serverCert, err := ioutil.ReadFile("/path/to/servercert.pem")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
pool.AppendCertsFromPEM(serverCert)
|
||||||
|
config := tls.Config{
|
||||||
|
RootCAs: pool,
|
||||||
|
}
|
||||||
|
|
||||||
|
w, err := DialWithTLSConfig(network, raddr, priority, tag, &config)
|
||||||
|
```
|
||||||
|
|
||||||
|
(Note that in both TLS cases, this uses a self-signed certificate, where the
|
||||||
|
remote syslog server has the keypair and the client has only the public key.)
|
||||||
|
|
||||||
|
And then to write log messages, continue like so:
|
||||||
|
|
||||||
|
```
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("failed to connect to syslog:", err)
|
||||||
|
}
|
||||||
|
defer w.Close()
|
||||||
|
|
||||||
|
w.Alert("this is an alert")
|
||||||
|
w.Crit("this is critical")
|
||||||
|
w.Err("this is an error")
|
||||||
|
w.Warning("this is a warning")
|
||||||
|
w.Notice("this is a notice")
|
||||||
|
w.Info("this is info")
|
||||||
|
w.Debug("this is debug")
|
||||||
|
w.Write([]byte("these are some bytes"))
|
||||||
|
```
|
||||||
|
|
||||||
|
# Generating TLS Certificates
|
||||||
|
|
||||||
|
We've provided a script that you can use to generate a self-signed keypair:
|
||||||
|
|
||||||
|
```
|
||||||
|
pip install cryptography
|
||||||
|
python script/gen-certs.py
|
||||||
|
```
|
||||||
|
|
||||||
|
That outputs the public key and private key to standard out. Put those into
|
||||||
|
`.pem` files. (And don't put them into any source control. The certificate in
|
||||||
|
the `test` directory is used by the unit tests, and please do not actually use
|
||||||
|
it anywhere else.)
|
||||||
|
|
||||||
|
# Running Tests
|
||||||
|
|
||||||
|
Run the tests as usual:
|
||||||
|
|
||||||
|
```
|
||||||
|
go test
|
||||||
|
```
|
||||||
|
|
||||||
|
But we've also provided a test coverage script that will show you which
|
||||||
|
lines of code are not covered:
|
||||||
|
|
||||||
|
```
|
||||||
|
script/coverage --html
|
||||||
|
```
|
||||||
|
|
||||||
|
That will open a new browser tab showing coverage information.
|
||||||
|
|
||||||
|
# License
|
||||||
|
|
||||||
|
This project uses the New BSD License, the same as the Go project itself.
|
||||||
|
|
||||||
|
# Code of Conduct
|
||||||
|
|
||||||
|
Please note that this project is released with a Contributor Code of Conduct.
|
||||||
|
By participating in this project you agree to abide by its terms.
|
68
vendor/src/github.com/RackSec/srslog/constants.go
vendored
Normal file
68
vendor/src/github.com/RackSec/srslog/constants.go
vendored
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
package srslog
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Priority is a combination of the syslog facility and
|
||||||
|
// severity. For example, LOG_ALERT | LOG_FTP sends an alert severity
|
||||||
|
// message from the FTP facility. The default severity is LOG_EMERG;
|
||||||
|
// the default facility is LOG_KERN.
|
||||||
|
type Priority int
|
||||||
|
|
||||||
|
const severityMask = 0x07
|
||||||
|
const facilityMask = 0xf8
|
||||||
|
|
||||||
|
const (
|
||||||
|
// Severity.
|
||||||
|
|
||||||
|
// From /usr/include/sys/syslog.h.
|
||||||
|
// These are the same on Linux, BSD, and OS X.
|
||||||
|
LOG_EMERG Priority = iota
|
||||||
|
LOG_ALERT
|
||||||
|
LOG_CRIT
|
||||||
|
LOG_ERR
|
||||||
|
LOG_WARNING
|
||||||
|
LOG_NOTICE
|
||||||
|
LOG_INFO
|
||||||
|
LOG_DEBUG
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// Facility.
|
||||||
|
|
||||||
|
// From /usr/include/sys/syslog.h.
|
||||||
|
// These are the same up to LOG_FTP on Linux, BSD, and OS X.
|
||||||
|
LOG_KERN Priority = iota << 3
|
||||||
|
LOG_USER
|
||||||
|
LOG_MAIL
|
||||||
|
LOG_DAEMON
|
||||||
|
LOG_AUTH
|
||||||
|
LOG_SYSLOG
|
||||||
|
LOG_LPR
|
||||||
|
LOG_NEWS
|
||||||
|
LOG_UUCP
|
||||||
|
LOG_CRON
|
||||||
|
LOG_AUTHPRIV
|
||||||
|
LOG_FTP
|
||||||
|
_ // unused
|
||||||
|
_ // unused
|
||||||
|
_ // unused
|
||||||
|
_ // unused
|
||||||
|
LOG_LOCAL0
|
||||||
|
LOG_LOCAL1
|
||||||
|
LOG_LOCAL2
|
||||||
|
LOG_LOCAL3
|
||||||
|
LOG_LOCAL4
|
||||||
|
LOG_LOCAL5
|
||||||
|
LOG_LOCAL6
|
||||||
|
LOG_LOCAL7
|
||||||
|
)
|
||||||
|
|
||||||
|
func validatePriority(p Priority) error {
|
||||||
|
if p < 0 || p > LOG_LOCAL7|LOG_DEBUG {
|
||||||
|
return errors.New("log/syslog: invalid priority")
|
||||||
|
} else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
53
vendor/src/github.com/RackSec/srslog/dialer.go
vendored
Normal file
53
vendor/src/github.com/RackSec/srslog/dialer.go
vendored
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
package srslog
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/tls"
|
||||||
|
"net"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (w Writer) getDialer() func() (serverConn, string, error) {
|
||||||
|
dialers := map[string]func() (serverConn, string, error){
|
||||||
|
"": w.unixDialer,
|
||||||
|
"tcp+tls": w.tlsDialer,
|
||||||
|
}
|
||||||
|
dialer, ok := dialers[w.network]
|
||||||
|
if !ok {
|
||||||
|
dialer = w.basicDialer
|
||||||
|
}
|
||||||
|
return dialer
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w Writer) unixDialer() (serverConn, string, error) {
|
||||||
|
sc, err := unixSyslog()
|
||||||
|
hostname := w.hostname
|
||||||
|
if hostname == "" {
|
||||||
|
hostname = "localhost"
|
||||||
|
}
|
||||||
|
return sc, hostname, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w Writer) tlsDialer() (serverConn, string, error) {
|
||||||
|
c, err := tls.Dial("tcp", w.raddr, w.tlsConfig)
|
||||||
|
var sc serverConn
|
||||||
|
hostname := w.hostname
|
||||||
|
if err == nil {
|
||||||
|
sc = &netConn{conn: c}
|
||||||
|
if hostname == "" {
|
||||||
|
hostname = c.LocalAddr().String()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sc, hostname, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w Writer) basicDialer() (serverConn, string, error) {
|
||||||
|
c, err := net.Dial(w.network, w.raddr)
|
||||||
|
var sc serverConn
|
||||||
|
hostname := w.hostname
|
||||||
|
if err == nil {
|
||||||
|
sc = &netConn{conn: c}
|
||||||
|
if hostname == "" {
|
||||||
|
hostname = c.LocalAddr().String()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sc, hostname, err
|
||||||
|
}
|
24
vendor/src/github.com/RackSec/srslog/net_conn.go
vendored
Normal file
24
vendor/src/github.com/RackSec/srslog/net_conn.go
vendored
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
package srslog
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net"
|
||||||
|
"os"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type netConn struct {
|
||||||
|
conn net.Conn
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *netConn) writeString(p Priority, hostname, tag, msg string) error {
|
||||||
|
timestamp := time.Now().Format(time.RFC3339)
|
||||||
|
_, err := fmt.Fprintf(n.conn, "<%d>%s %s %s[%d]: %s",
|
||||||
|
p, timestamp, hostname,
|
||||||
|
tag, os.Getpid(), msg)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *netConn) close() error {
|
||||||
|
return n.conn.Close()
|
||||||
|
}
|
96
vendor/src/github.com/RackSec/srslog/srslog.go
vendored
Normal file
96
vendor/src/github.com/RackSec/srslog/srslog.go
vendored
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
package srslog
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/tls"
|
||||||
|
"crypto/x509"
|
||||||
|
"io/ioutil"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
// This interface and the separate syslog_unix.go file exist for
|
||||||
|
// Solaris support as implemented by gccgo. On Solaris you can not
|
||||||
|
// simply open a TCP connection to the syslog daemon. The gccgo
|
||||||
|
// sources have a syslog_solaris.go file that implements unixSyslog to
|
||||||
|
// return a type that satisfies this interface and simply calls the C
|
||||||
|
// library syslog function.
|
||||||
|
type serverConn interface {
|
||||||
|
writeString(p Priority, hostname, tag, s string) error
|
||||||
|
close() error
|
||||||
|
}
|
||||||
|
|
||||||
|
// New establishes a new connection to the system log daemon. Each
|
||||||
|
// write to the returned Writer sends a log message with the given
|
||||||
|
// priority and prefix.
|
||||||
|
func New(priority Priority, tag string) (w *Writer, err error) {
|
||||||
|
return Dial("", "", priority, tag)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dial establishes a connection to a log daemon by connecting to
|
||||||
|
// address raddr on the specified network. Each write to the returned
|
||||||
|
// Writer sends a log message with the given facility, severity and
|
||||||
|
// tag.
|
||||||
|
// If network is empty, Dial will connect to the local syslog server.
|
||||||
|
func Dial(network, raddr string, priority Priority, tag string) (*Writer, error) {
|
||||||
|
return DialWithTLSConfig(network, raddr, priority, tag, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DialWithTLSCertPath establishes a secure connection to a log daemon by connecting to
|
||||||
|
// address raddr on the specified network. It uses certPath to load TLS certificates and configure
|
||||||
|
// the secure connection.
|
||||||
|
func DialWithTLSCertPath(network, raddr string, priority Priority, tag, certPath string) (*Writer, error) {
|
||||||
|
pool := x509.NewCertPool()
|
||||||
|
serverCert, err := ioutil.ReadFile(certPath)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
pool.AppendCertsFromPEM(serverCert)
|
||||||
|
config := tls.Config{
|
||||||
|
RootCAs: pool,
|
||||||
|
}
|
||||||
|
|
||||||
|
return DialWithTLSConfig(network, raddr, priority, tag, &config)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DialWithTLSConfig establishes a secure connection to a log daemon by connecting to
|
||||||
|
// address raddr on the specified network. It uses tlsConfig to configure the secure connection.
|
||||||
|
func DialWithTLSConfig(network, raddr string, priority Priority, tag string, tlsConfig *tls.Config) (*Writer, error) {
|
||||||
|
if err := validatePriority(priority); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if tag == "" {
|
||||||
|
tag = os.Args[0]
|
||||||
|
}
|
||||||
|
hostname, _ := os.Hostname()
|
||||||
|
|
||||||
|
w := &Writer{
|
||||||
|
priority: priority,
|
||||||
|
tag: tag,
|
||||||
|
hostname: hostname,
|
||||||
|
network: network,
|
||||||
|
raddr: raddr,
|
||||||
|
tlsConfig: tlsConfig,
|
||||||
|
}
|
||||||
|
|
||||||
|
w.Lock()
|
||||||
|
defer w.Unlock()
|
||||||
|
|
||||||
|
err := w.connect()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return w, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewLogger creates a log.Logger whose output is written to
|
||||||
|
// the system log service with the specified priority. The logFlag
|
||||||
|
// argument is the flag set passed through to log.New to create
|
||||||
|
// the Logger.
|
||||||
|
func NewLogger(p Priority, logFlag int) (*log.Logger, error) {
|
||||||
|
s, err := New(p, "")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return log.New(s, "", logFlag), nil
|
||||||
|
}
|
47
vendor/src/github.com/RackSec/srslog/srslog_unix.go
vendored
Normal file
47
vendor/src/github.com/RackSec/srslog/srslog_unix.go
vendored
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
package srslog
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"net"
|
||||||
|
"os"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// unixSyslog opens a connection to the syslog daemon running on the
|
||||||
|
// local machine using a Unix domain socket.
|
||||||
|
|
||||||
|
func unixSyslog() (conn serverConn, err error) {
|
||||||
|
logTypes := []string{"unixgram", "unix"}
|
||||||
|
logPaths := []string{"/dev/log", "/var/run/syslog", "/var/run/log"}
|
||||||
|
for _, network := range logTypes {
|
||||||
|
for _, path := range logPaths {
|
||||||
|
conn, err := net.Dial(network, path)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
} else {
|
||||||
|
return &localConn{conn: conn}, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, errors.New("Unix syslog delivery error")
|
||||||
|
}
|
||||||
|
|
||||||
|
type localConn struct {
|
||||||
|
conn net.Conn
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *localConn) writeString(p Priority, hostname, tag, msg string) error {
|
||||||
|
// Compared to the network form at srslog.netConn, the changes are:
|
||||||
|
// 1. Use time.Stamp instead of time.RFC3339.
|
||||||
|
// 2. Drop the hostname field from the Fprintf.
|
||||||
|
timestamp := time.Now().Format(time.Stamp)
|
||||||
|
_, err := fmt.Fprintf(n.conn, "<%d>%s %s[%d]: %s",
|
||||||
|
p, timestamp,
|
||||||
|
tag, os.Getpid(), msg)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *localConn) close() error {
|
||||||
|
return n.conn.Close()
|
||||||
|
}
|
152
vendor/src/github.com/RackSec/srslog/writer.go
vendored
Normal file
152
vendor/src/github.com/RackSec/srslog/writer.go
vendored
Normal file
|
@ -0,0 +1,152 @@
|
||||||
|
package srslog
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/tls"
|
||||||
|
"strings"
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
// A Writer is a connection to a syslog server.
|
||||||
|
type Writer struct {
|
||||||
|
sync.Mutex // guards conn
|
||||||
|
|
||||||
|
priority Priority
|
||||||
|
tag string
|
||||||
|
hostname string
|
||||||
|
network string
|
||||||
|
raddr string
|
||||||
|
tlsConfig *tls.Config
|
||||||
|
|
||||||
|
conn serverConn
|
||||||
|
}
|
||||||
|
|
||||||
|
// connect makes a connection to the syslog server.
|
||||||
|
// It must be called with w.mu held.
|
||||||
|
func (w *Writer) connect() (err error) {
|
||||||
|
if w.conn != nil {
|
||||||
|
// ignore err from close, it makes sense to continue anyway
|
||||||
|
w.conn.close()
|
||||||
|
w.conn = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var conn serverConn
|
||||||
|
var hostname string
|
||||||
|
dialer := w.getDialer()
|
||||||
|
conn, hostname, err = dialer()
|
||||||
|
if err == nil {
|
||||||
|
w.conn = conn
|
||||||
|
w.hostname = hostname
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write sends a log message to the syslog daemon using the default priority
|
||||||
|
// passed into `srslog.New` or the `srslog.Dial*` functions.
|
||||||
|
func (w *Writer) Write(b []byte) (int, error) {
|
||||||
|
return w.writeAndRetry(w.priority, string(b))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close closes a connection to the syslog daemon.
|
||||||
|
func (w *Writer) Close() error {
|
||||||
|
w.Lock()
|
||||||
|
defer w.Unlock()
|
||||||
|
|
||||||
|
if w.conn != nil {
|
||||||
|
err := w.conn.close()
|
||||||
|
w.conn = nil
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Emerg logs a message with severity LOG_EMERG; this overrides the default
|
||||||
|
// priority passed to `srslog.New` and the `srslog.Dial*` functions.
|
||||||
|
func (w *Writer) Emerg(m string) (err error) {
|
||||||
|
_, err = w.writeAndRetry(LOG_EMERG, m)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Alert logs a message with severity LOG_ALERT; this overrides the default
|
||||||
|
// priority passed to `srslog.New` and the `srslog.Dial*` functions.
|
||||||
|
func (w *Writer) Alert(m string) (err error) {
|
||||||
|
_, err = w.writeAndRetry(LOG_ALERT, m)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Crit logs a message with severity LOG_CRIT; this overrides the default
|
||||||
|
// priority passed to `srslog.New` and the `srslog.Dial*` functions.
|
||||||
|
func (w *Writer) Crit(m string) (err error) {
|
||||||
|
_, err = w.writeAndRetry(LOG_CRIT, m)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Err logs a message with severity LOG_ERR; this overrides the default
|
||||||
|
// priority passed to `srslog.New` and the `srslog.Dial*` functions.
|
||||||
|
func (w *Writer) Err(m string) (err error) {
|
||||||
|
_, err = w.writeAndRetry(LOG_ERR, m)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Warning logs a message with severity LOG_WARNING; this overrides the default
|
||||||
|
// priority passed to `srslog.New` and the `srslog.Dial*` functions.
|
||||||
|
func (w *Writer) Warning(m string) (err error) {
|
||||||
|
_, err = w.writeAndRetry(LOG_WARNING, m)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Notice logs a message with severity LOG_NOTICE; this overrides the default
|
||||||
|
// priority passed to `srslog.New` and the `srslog.Dial*` functions.
|
||||||
|
func (w *Writer) Notice(m string) (err error) {
|
||||||
|
_, err = w.writeAndRetry(LOG_NOTICE, m)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Info logs a message with severity LOG_INFO; this overrides the default
|
||||||
|
// priority passed to `srslog.New` and the `srslog.Dial*` functions.
|
||||||
|
func (w *Writer) Info(m string) (err error) {
|
||||||
|
_, err = w.writeAndRetry(LOG_INFO, m)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Debug logs a message with severity LOG_DEBUG; this overrides the default
|
||||||
|
// priority passed to `srslog.New` and the `srslog.Dial*` functions.
|
||||||
|
func (w *Writer) Debug(m string) (err error) {
|
||||||
|
_, err = w.writeAndRetry(LOG_DEBUG, m)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *Writer) writeAndRetry(p Priority, s string) (int, error) {
|
||||||
|
pr := (w.priority & facilityMask) | (p & severityMask)
|
||||||
|
|
||||||
|
w.Lock()
|
||||||
|
defer w.Unlock()
|
||||||
|
|
||||||
|
if w.conn != nil {
|
||||||
|
if n, err := w.write(pr, s); err == nil {
|
||||||
|
return n, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err := w.connect(); err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return w.write(pr, s)
|
||||||
|
}
|
||||||
|
|
||||||
|
// write generates and writes a syslog formatted string. The
|
||||||
|
// format is as follows: <PRI>TIMESTAMP HOSTNAME TAG[PID]: MSG
|
||||||
|
func (w *Writer) write(p Priority, msg string) (int, error) {
|
||||||
|
// ensure it ends in a \n
|
||||||
|
if !strings.HasSuffix(msg, "\n") {
|
||||||
|
msg += "\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
err := w.conn.writeString(p, w.hostname, w.tag, msg)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
// Note: return the length of the input, not the number of
|
||||||
|
// bytes printed by Fprintf, because this must behave like
|
||||||
|
// an io.Writer.
|
||||||
|
return len(msg), nil
|
||||||
|
}
|
Loading…
Reference in a new issue