Skip to content

Commit

Permalink
Merge pull request #1969 from yunkon-kim/250210-21
Browse files Browse the repository at this point in the history
Improve API password protection
  • Loading branch information
seokho-son authored Feb 11, 2025
2 parents 424b6c1 + e4d13d9 commit 80de090
Show file tree
Hide file tree
Showing 11 changed files with 169 additions and 72 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
*.dll
*.so
*.dylib
cmd/bcrypt/bcrypt

# Keys
*.pem
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ ENV TB_ROOT_PATH=/app \
TB_AUTH_JWT_SIGNING_METHOD=RS256 \
TB_AUTH_JWT_PUBLICKEY= \
TB_API_USERNAME=default \
TB_API_PASSWORD=default \
TB_API_PASSWORD='$2a$10$4PKzCuJ6fPYsbCF.HR//ieLjaCzBAdwORchx62F2JRXQsuR3d9T0q' \
TB_AUTOCONTROL_DURATION_MS=10000 \
TB_SELF_ENDPOINT=localhost:1323 \
TB_DEFAULT_NAMESPACE=default \
Expand Down
16 changes: 16 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,19 @@ swag swagger:
# make compose will build and run the docker-compose file (DOCKER_BUILDKIT is for quick build)
compose:
DOCKER_BUILDKIT=1 docker compose up --build

bcrypt: ## Generate bcrypt hash for given password (usage: make bcrypt PASSWORD=mypassword)
@if [ -z "$(PASSWORD)" ]; then \
echo "Please provide a password: make bcrypt PASSWORD=mypassword"; \
exit 1; \
fi
@mkdir -p cmd/bcrypt
@if [ ! -f "cmd/bcrypt/bcrypt" ]; then \
echo "bcrypt binary not found, building it..."; \
go build -o cmd/bcrypt/bcrypt cmd/bcrypt/main.go; \
chmod +x cmd/bcrypt/bcrypt; \
fi
@echo "$(PASSWORD)" | ./cmd/bcrypt/bcrypt

help: ## Display this help screen
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
41 changes: 41 additions & 0 deletions cmd/bcrypt/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# TB API Password Configuration Guide

## Generating Password Hash

1. From the CB-Tumblebug root directory, generate a bcrypt hash of your password using:

```shell
make bcrypt PASSWORD=yourpassword
```

2. Copy the generated hash value.

## Configuring the Password

### Using Docker Compose

1. Open `docker-compose.yaml` and update the `TB_API_PASSWORD` environment variable with ($$):
```yaml
environment:
- TB_API_PASSWORD=$$2a$$10$$4PKzCuJ6fPYsbCF.HR//ieLjaCzBAdwORchx62F2JRXQsuR3d9T0q
```
### Using Environment File
1. If you're using `setup.env`, update the password hash:
```shell
TB_API_PASSWORD='$2a$10$4PKzCuJ6fPYsbCF.HR//ieLjaCzBAdwORchx62F2JRXQsuR3d9T0q'
```

### Using Dockerfile

1. If you're building directly with Dockerfile, update the environment variable with (' '):
```dockerfile
ENV TB_API_PASSWORD='$2a$10$4PKzCuJ6fPYsbCF.HR//ieLjaCzBAdwORchx62F2JRXQsuR3d9T0q'
```

## Notes

- Always keep your password hash secure
- Never commit the actual password or hash to version control
- The hash should be properly escaped if it contains special characters
59 changes: 59 additions & 0 deletions cmd/bcrypt/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package main

import (
"bufio"
"flag"
"fmt"
"os"
"strings"

"golang.org/x/crypto/bcrypt"
)

func hashPassword(password string) (string, error) {
bytes, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
return string(bytes), err
}

func verifyPassword(password, hash string) bool {
err := bcrypt.CompareHashAndPassword([]byte(hash), []byte(password))
return err == nil
}

func main() {
verify := flag.Bool("verify", false, "Verify a password against a hash")
flag.Parse()

reader := bufio.NewReader(os.Stdin)

if *verify {
fmt.Print("Enter hash: ")
hash, _ := reader.ReadString('\n')
hash = strings.TrimSpace(hash)

fmt.Print("Enter password to verify: ")
password, _ := reader.ReadString('\n')
password = strings.TrimSpace(password)

if verifyPassword(password, hash) {
fmt.Println("Password is valid!")
} else {
fmt.Println("Password is invalid!")
}
return
}

fmt.Print("Enter password to hash: ")
password, _ := reader.ReadString('\n')
password = strings.TrimSpace(password)

hash, err := hashPassword(password)
if err != nil {
fmt.Printf("Error hashing password: %v\n", err)
os.Exit(1)
}

fmt.Printf("Bcrypt hash: %s\n", hash)
fmt.Printf(" - For docker-compose.yaml and .env (with $$): %s\n", strings.ReplaceAll(hash, "$", "$$"))
fmt.Printf(" - For Dockerfile or environment variables (with ' '): '%s'\n", hash)
}
2 changes: 1 addition & 1 deletion conf/setup.env
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export TB_ROOT_PATH=`cd $SCRIPT_DIR && cd .. && pwd`

# Set API access config
export TB_API_USERNAME=default
export TB_API_PASSWORD=default
export TB_API_PASSWORD='$2a$10$4PKzCuJ6fPYsbCF.HR//ieLjaCzBAdwORchx62F2JRXQsuR3d9T0q'
## TB_ALLOW_ORIGINS (ex: https://cloud-barista.org,http://localhost:8080 or * for all)
export TB_ALLOW_ORIGINS=*
## Set TB_AUTH_ENABLED=true currently for basic auth for all routes (i.e., url or path)
Expand Down
32 changes: 15 additions & 17 deletions docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ services:
- external_network
ports:
- 1323:1323
depends_on:
depends_on:
- cb-tumblebug-etcd
# - cb-tumblebug-etcd-conf
- cb-spider
- cb-spider
volumes:
- ./conf/:/app/conf/
- ./container-volume/cb-tumblebug-container/meta_db/:/app/meta_db/
Expand All @@ -36,14 +36,14 @@ services:
# - TB_ETCD_AUTH_ENABLED=false
# - TB_ETCD_USERNAME=default
# - TB_ETCD_PASSWORD=default
# - TB_SQLITE_URL=localhost:3306
# - TB_SQLITE_DATABASE=cb_tumblebug
# - TB_SQLITE_USER=cb_tumblebug
# - TB_SQLITE_PASSWORD=cb_tumblebug
# - TB_SQLITE_URL=localhost:3306
# - TB_SQLITE_DATABASE=cb_tumblebug
# - TB_SQLITE_USER=cb_tumblebug
# - TB_SQLITE_PASSWORD=cb_tumblebug
# - TB_ALLOW_ORIGINS=*
# - TB_AUTH_ENABLED=true
# - TB_API_USERNAME=default
# - TB_API_PASSWORD=default
# - TB_API_PASSWORD=$$2a$$10$$4PKzCuJ6fPYsbCF.HR//ieLjaCzBAdwORchx62F2JRXQsuR3d9T0q
# - TB_AUTOCONTROL_DURATION_MS=10000
# - TB_DRAGONFLY_REST_URL=http://cb-dragonfly:9090/dragonfly
# - TB_DEFAULT_NAMESPACE=default
Expand All @@ -57,7 +57,7 @@ services:
# - TB_LOGWRITER=both
# - TB_NODE_ENV=development
healthcheck: # for CB-Tumblebug
test: [ "CMD", "curl", "-f", "http://localhost:1323/tumblebug/readyz" ]
test: ["CMD", "curl", "-f", "http://localhost:1323/tumblebug/readyz"]
interval: 1m
timeout: 5s
retries: 3
Expand All @@ -72,7 +72,7 @@ services:
ports:
- 2379:2379
- 2380:2380
volumes:
volumes:
- ./container-volume/etcd/data:/etcd-data
entrypoint: /usr/local/bin/etcd
command:
Expand Down Expand Up @@ -103,7 +103,7 @@ services:
- --auth-token
- simple
healthcheck: # for etcd
test: [ "CMD", "/usr/local/bin/etcd", "--version"]
test: ["CMD", "/usr/local/bin/etcd", "--version"]
interval: 1m
timeout: 5s
retries: 3
Expand All @@ -115,10 +115,10 @@ services:
container_name: cb-spider
# build:
# context: ../cb-spider
# dockerfile: Dockerfile
# dockerfile: Dockerfile
networks:
- internal_network
- external_network # for outbound access (not ideal for security)
- external_network # for outbound access (not ideal for security)
# expose:
# - 1024
ports:
Expand All @@ -136,7 +136,7 @@ services:
- SPIDER_HISCALL_LOG_LEVEL=error
- ID_TRANSFORM_MODE=OFF
healthcheck: # for CB-Spider
test: [ "CMD", "curl", "-f", "http://localhost:1024/spider/readyz" ]
test: ["CMD", "curl", "-f", "http://localhost:1024/spider/readyz"]
interval: 1m
timeout: 5s
retries: 3
Expand Down Expand Up @@ -168,7 +168,7 @@ services:
# container_name: mc-terrarium
# # build:
# # context: .
# # dockerfile: Dockerfile
# # dockerfile: Dockerfile
# networks:
# - external_network
# ports:
Expand Down Expand Up @@ -205,7 +205,6 @@ services:
# retries: 3
# start_period: 10s


# # Swagger UI
# swagger-ui:
# image: swaggerapi/swagger-ui
Expand All @@ -219,7 +218,7 @@ services:
# - ./src/api/rest/docs/swagger.yaml:/swagger.yaml
# environment:
# # Options: https://github.com/swagger-api/swagger-ui/blob/37b8c1a8b67200dd425216ab8f97b725a429a5c0/docs/usage/configuration.md#docker
# - SWAGGER_JSON=/swagger.yaml
# - SWAGGER_JSON=/swagger.yaml
# - QUERY_CONFIG_ENABLED=true
# logging:
# # Disable logging
Expand Down Expand Up @@ -256,4 +255,3 @@ services:
# timeout: 10s
# retries: 3
# start_period: 10s

6 changes: 3 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,13 @@ require (
github.com/google/gofuzz v1.2.0 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/gorilla/websocket v1.5.0 // indirect
github.com/imdario/mergo v0.3.6 // indirect
github.com/moby/spdystream v0.4.0 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect
github.com/x448/float16 v0.8.4 // indirect
golang.org/x/oauth2 v0.21.0 // indirect
golang.org/x/term v0.22.0 // indirect
golang.org/x/term v0.27.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
k8s.io/apimachinery v0.31.3 // indirect
k8s.io/klog/v2 v2.130.1 // indirect
Expand All @@ -71,7 +72,6 @@ require (
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/goccy/go-json v0.10.3 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang-jwt/jwt v3.2.2+incompatible // indirect
github.com/golang/protobuf v1.5.4 // indirect
github.com/golang/snappy v0.0.4 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
Expand Down Expand Up @@ -117,7 +117,7 @@ require (
go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.26.0 // indirect
golang.org/x/exp v0.0.0-20240112132812-db7319d0e0e3 // indirect
golang.org/x/net v0.33.0
golang.org/x/net v0.33.0 // indirect
golang.org/x/sys v0.28.0 // indirect
golang.org/x/text v0.21.0 // indirect
golang.org/x/time v0.8.0 // indirect
Expand Down
Loading

0 comments on commit 80de090

Please sign in to comment.