implement docker image blacklist

This commit is contained in:
yusing 2025-02-24 06:47:07 +08:00
parent 080c1cee4f
commit b7e9a85be0
4 changed files with 89 additions and 31 deletions

View file

@ -51,7 +51,7 @@ var DummyContainer = new(Container)
func FromDocker(c *container.Summary, dockerHost string) (res *Container) { func FromDocker(c *container.Summary, dockerHost string) (res *Container) {
isExplicit := false isExplicit := false
helper := containerHelper{c} helper := containerHelper{Summary: c}
for lbl := range c.Labels { for lbl := range c.Labels {
if strings.HasPrefix(lbl, NSProxy+".") { if strings.HasPrefix(lbl, NSProxy+".") {
isExplicit = true isExplicit = true
@ -63,7 +63,6 @@ func FromDocker(c *container.Summary, dockerHost string) (res *Container) {
DockerHost: dockerHost, DockerHost: dockerHost,
ContainerName: helper.getName(), ContainerName: helper.getName(),
ContainerID: c.ID, ContainerID: c.ID,
ImageName: helper.getImageName(),
Labels: c.Labels, Labels: c.Labels,

View file

@ -7,9 +7,17 @@ import (
"github.com/yusing/go-proxy/internal/utils/strutils" "github.com/yusing/go-proxy/internal/utils/strutils"
) )
type containerHelper struct { type (
containerHelper struct {
*container.Summary *container.Summary
image *ContainerImage
} }
ContainerImage struct {
Author string
Name string
Tag string
}
)
// getDeleteLabel gets the value of a label and then deletes it from the container. // getDeleteLabel gets the value of a label and then deletes it from the container.
// If the label does not exist, an empty string is returned. // If the label does not exist, an empty string is returned.
@ -32,10 +40,21 @@ func (c containerHelper) getName() string {
return strings.TrimPrefix(c.Names[0], "/") return strings.TrimPrefix(c.Names[0], "/")
} }
func (c containerHelper) getImageName() string { func (c containerHelper) parseImage() *ContainerImage {
colonSep := strutils.SplitRune(c.Image, ':') colonSep := strutils.SplitRune(c.Image, ':')
slashSep := strutils.SplitRune(colonSep[0], '/') slashSep := strutils.SplitRune(colonSep[0], '/')
return slashSep[len(slashSep)-1] im := new(ContainerImage)
if len(slashSep) > 1 {
im.Author = slashSep[len(slashSep)-1]
im.Name = strings.Join(slashSep[:len(slashSep)-1], "/")
} else {
im.Author = "library"
im.Name = colonSep[0]
}
if len(colonSep) > 1 {
im.Tag = colonSep[1]
}
return im
} }
func (c containerHelper) getPublicPortMapping() PortMapping { func (c containerHelper) getPublicPortMapping() PortMapping {
@ -57,28 +76,9 @@ func (c containerHelper) getPrivatePortMapping() PortMapping {
return res return res
} }
var databaseMPs = map[string]struct{}{ func (c containerHelper) IsBlacklisted() bool {
"/var/lib/postgresql/data": {}, if c.image == nil {
"/var/lib/mysql": {}, c.image = c.parseImage()
"/var/lib/mongodb": {},
"/var/lib/mariadb": {},
"/var/lib/memcached": {},
"/var/lib/rabbitmq": {},
} }
return c.image.IsBlacklisted()
func (c containerHelper) isDatabase() bool {
for _, m := range c.Mounts {
if _, ok := databaseMPs[m.Destination]; ok {
return true
}
}
for _, v := range c.Ports {
switch v.PrivatePort {
// postgres, mysql or mariadb, redis, memcached, mongodb
case 5432, 3306, 6379, 11211, 27017:
return true
}
}
return false
} }

View file

@ -0,0 +1,59 @@
package docker
var imageBlacklist = map[string]struct{}{
// pure databases without UI
"postgres": {},
"mysql": {},
"mariadb": {},
"redis": {},
"memcached": {},
"mongo": {},
"rabbitmq": {},
"couchdb": {},
"neo4j": {},
"telegraf": {},
// search engines, usually used for internal services
"elasticsearch": {},
"meilisearch": {},
"kibana": {},
"solr": {},
}
var imageBlacklistFullname = map[string]struct{}{
// headless browsers
"gcr.io/zenika-hub/alpine-chrome": {},
"eu.gcr.io/zenika-hub/alpine-chrome": {},
"us.gcr.io/zenika-hub/alpine-chrome": {},
"asia.gcr.io/zenika-hub/alpine-chrome": {},
// image update watchers
"watchtower": {},
"getwud/wud": {},
}
var authorBlacklist = map[string]struct{}{
// headless browsers
"selenium": {},
"browserless": {},
"zenika": {},
"zabbix": {},
// docker
"moby": {},
"docker": {},
}
func (image *ContainerImage) IsBlacklisted() bool {
_, ok := imageBlacklist[image.Name]
if ok {
return true
}
_, ok = imageBlacklistFullname[image.Author+":"+image.Name]
if ok {
return true
}
_, ok = authorBlacklist[image.Author]
return ok
}

View file

@ -215,7 +215,7 @@ func (r *Route) ShouldExclude() bool {
return true return true
case r.IsZeroPort() && !r.UseIdleWatcher(): case r.IsZeroPort() && !r.UseIdleWatcher():
return true return true
case r.Container.IsDatabase && !r.Container.IsExplicit: case !r.Container.IsExplicit && r.Container.IsBlacklisted():
return true return true
case strings.HasPrefix(r.Container.ContainerName, "buildx_"): case strings.HasPrefix(r.Container.ContainerName, "buildx_"):
return true return true