Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

private feeds via nginx reverse proxy (workaround) #515

Open
jsiedentop opened this issue May 9, 2020 · 7 comments
Open

private feeds via nginx reverse proxy (workaround) #515

jsiedentop opened this issue May 9, 2020 · 7 comments

Comments

@jsiedentop
Copy link

jsiedentop commented May 9, 2020

Several people would like to run a private nuget feed. The depending pull request is open for 2 years now. It seems that this could take a while to be published. #69

I provide the baget service behind a nuget reverse proxy where nginx takes over the authentification part. In combination with docker compose this works quite well. I think this is a nice workaround as long the pull request is open.

The nginx site configuration:

server {
  listen 80;
  server_name packages.myawesomeproject.com;

  proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header   X-Forwarded-Proto $scheme;
  proxy_set_header   Host $host;

  location / {
    auth_basic "Resticted Content";
    auth_basic_user_file /etc/nginx/.htpasswd;
    proxy_pass http://baget:80;
  }

creating the htpasswd file:

sudo sh -c "echo -n '[username]:' >> /etc/nginx/.htpasswd"
sudo sh -c "openssl passwd -apr1 >> /etc/nginx/.htpasswd"

As many people didn't know how nuget auth works exactly it would be nice to add this way to the documentation. An all in one docker-compose file with nginx and baget would be awesome.

@pierrediancourt
Copy link

You can also filter by IP as follow :

        location / {
		satisfy all;
                allow 127.0.0.1;
                allow xxx.xxx.xxx.xxx;
                deny all;

                proxy_max_temp_file_size 2048m;

                proxy_pass http://baget;
                proxy_set_header Host $http_host;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                ... etc ...
        }

This is totally compatible with @jsiedentop's answer.

NB : I had to increase the "proxy_max_temp_file_size" value for my usage.

@johanneswdm
Copy link

But how is it possible to authenticate when using the included symbol-server? It seems like Visual Studio has no built-in option to use password-protected symbol servers and it returns me a 401: Unauthorized.

@abakumov-v
Copy link

Hello! @jsiedentop @pierrediancourt can you present full docker-compose.yml and nginx conf files? I'm trying set up nginx and baget but when I send request to "/" I'm getting 502 Bad Gateway error from nginx...

@pierrediancourt
Copy link

pierrediancourt commented Aug 21, 2020

Hi @abakumov-v,
Here's something that works.
It may not be the prettier or easier way as i didn't put a lot of time into it.
Just pop a thumb up on this message if that helps you ;)
Let's avoid flooding this topic !

version: '3'

services:
  baget:
    image: loicsharma/baget:latest
    restart: unless-stopped
    container_name: packagemanager_baget
    hostname: baget
    expose:
      - 80
    environment:
      - ASPNETCORE_ENVIRONMENT=Release
      - ApiKey=xxxxxxxxxxxxxxxxxx
      - PackageDeletionBehavior=Unlist
      - AllowPackageOverwrites=true
      - Storage__Type=FileSystem
      - Storage__Path=/var/baget/packages
      - Database__Type=PostgreSql
      - Database__ConnectionString=User ID=baget;Password=MySuperPassword;Host=postgres;Port=5432;Database=baget;
      - Search__Type=Database
      - Mirror__Enable=true
      - Mirror__PackageSource="https://api.nuget.org/v3/index.json"
    volumes:
      - baget_data:/var/baget

  postgres:
    image: postgres:12.3-alpine
    restart: unless-stopped
    container_name: packagemanager_postgres
    hostname: postgres
    expose:
      - 5432
    environment:
      - POSTGRES_USER=baget
      - POSTGRES_PASSWORD=MySuperPassword
      - POSTGRES_DB=baget
    volumes:
      # This needs explicit mapping due to https://github.com/docker-library/postgres/blob/4e48e3228a30763913ece952c611e5e9b95c8759/Dockerfile.template#L52
      - postgres_data:/var/lib/postgresql/data

volumes:
  baget_data:
  postgres_data:

nginx config :

upstream baget{
    server packagemanager_baget:80;
}

server {
    listen 80;
    server_name baget.example.com;

    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl;
    server_name baget.example.com;

     # managing the ssl/tls traffic decryption, dependant on your setup, this is just an example
     ssl_certificate /etc/letsencrypt/live/xxx/fullchain.pem;
     ssl_certificate_key /etc/letsencrypt/live/xxx/privkey.pem;
     ssl_protocols         TLSv1.2; # obsolete : SSLv3 TLSv1 TLSv1.1 
    ssl_ciphers           ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384;
    ssl_session_cache     shared:SSL:20m;
    ssl_session_timeout   4h;

    # blocking the search engines
    location = /robots.txt {
        add_header Content-Type text/plain;
        return 200 "User-agent: *\nDisallow: /\n";
    }

    location / {
        # blacklisting every ip but these :
        satisfy all;
        allow 000.000.000.000; # my public ip accessing this service
        allow 000.000.000.001; # another ip allowed to access
        deny all;

        proxy_max_temp_file_size 2048m; # optional and depends on the size of the things that are uploaded/downloaded through nginx 

        proxy_pass http://baget;
        proxy_redirect off;
        proxy_set_header X-NginX-Proxy true;
        proxy_set_header Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

@aleks73337
Copy link

aleks73337 commented Oct 6, 2020

@pierrediancourt, It also works if your baget server in kubernetes. Without it, kubernetes resolves it's own virtual IP. But with your config, it works fine!

@wojtek-viirtue
Copy link

Posting the required K8s manifest here just in case anyone wants to run this in kubernetes.

Note: I SSL offload at a load balancer so the configuration is all over http, but it should simple enough to tweak for your own use case.

kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: baget-nuget-server-pvc
spec:
  storageClassName: kadalu.replica3
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 1Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: baget-nuget-server
spec:
  selector:
    matchLabels:
      app: baget-nuget-server
  template:
    metadata:
      labels:
        app: baget-nuget-server
    spec:
      containers:
      - name: baget-nuget-server
        image: loicsharma/baget:latest
        env:
          - name: ASPNETCORE_ENVIRONMENT
            value: Releae

          - name: ApiKey
            value: XXXXXXXXXXXXXXX

          - name: Storage__Type
            value: FileSystem

          - name: Storage__Path
            value: /var/baget/packages

          - name: Database__Type
            value: Sqlite

          - name: Database__ConnectionString
            value: Data Source=/var/baget/baget.db
          
          - name: Search__Type
            value: Database
          
        resources:
          limits:
            memory: "512Mi"
            cpu: "500m"
        ports:
        - containerPort: 80

        volumeMounts:
          - mountPath: /var/baget/packages
            name: baget-packages

      volumes:
        - name: baget-packages
          persistentVolumeClaim:
            claimName: baget-nuget-server-pvc 
---
kind: Service
apiVersion: v1
metadata:
  name:  baget-nuget-server
spec:
  selector:
    app:  baget-nuget-server
  type:  ClusterIP
  ports:
  - name:  http
    port:  80
    targetPort:  80
---
apiVersion: v1
data:
  auth: XXXXXXXXXXXXXXX
kind: Secret
metadata:
  name: basic-auth
type: Opaque
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-baget
  annotations:
    nginx.ingress.kubernetes.io/auth-type: basic
    nginx.ingress.kubernetes.io/auth-secret: basic-auth
    nginx.ingress.kubernetes.io/auth-realm: 'Authentication Required - Nuget Server'
    kubernetes.io/ingress.class: nginx
spec:
  rules:
  - host: nuget.yourdomain.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
            service:
              name: baget-nuget-server
              port: 
                number: 80

@aleks73337
Copy link

aleks73337 commented Jan 20, 2021 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants