shelf
shelf copied to clipboard
How to implement a secure Dart server?
Components
- Host OS: Debian 10
- Docker version: 20.10.14, build a224086
- Docker-compose version: 2.4.1
- Dart container image source: https://hub.docker.com/_/dart
Structure of my Docker project
.
├── certs
│ ├── cert.pem
│ ├── fullchain.pem
│ └── key.pem
├── dart
│ └── fileserver
│ ├── files
│ └── source
└── docker-compose.yaml
- source directory contains Dart source files.
- certs directory contains certificates issued by acme.sh.
- files directory is a repository for server.
-
source/Dockerfile file is created by Dart when using
server-shelf
template
docker-compose.yaml
version: "3.8"
services:
fileserver:
build:
context: ./dart/fileserver/source
container_name: cyp-fs
restart: always
networks:
innet:
ipv4_address: 172.27.0.5
ports:
- 8080:8080
- 443:443
volumes:
- ./dart/fileserver/files:/files
- ./certs:/certs
networks:
# red interna usada por los contenedores únicamente
innet:
driver: bridge
ipam:
config:
- subnet: 172.27.0.0/16
dart/fileserver/source/bin/server.dart
import 'dart:io';
import 'package:shelf/shelf.dart';
import 'package:shelf/shelf_io.dart';
import 'package:shelf_router/shelf_router.dart';
import 'package:cyp_files_server/src/exports.dart';
// Configure routes.
final _router = Router()
..mount('/private/images/', ImagesApi('files/private/spare_parts/images').router)
..mount('/public/text/', StaticAssetsApi('files/public/assets/static_files/text').router)
..all('/<name|.*>', fallback());
SecurityContext getSecurityContext() { // Bind with a secure HTTPS connection
final chain = Platform.script.resolve('certs/fullchain.pem').toFilePath();
final key = Platform.script.resolve('certs/key.pem').toFilePath();
return SecurityContext()
..useCertificateChain(chain)
..usePrivateKey(key, password: 'dartdart');
}
void main(List<String> args) async {
final useSecureConn = true;
final context = useSecureConn ? getSecurityContext() : null;
// Use any available host or container IP (usually `0.0.0.0`).
final ip = InternetAddress.anyIPv4;
final _handler = Pipeline()
.addMiddleware(logRequests()) // logs requests
.addMiddleware(handleCors())
.addMiddleware(handleAuth(Env.jwtSecret))
.addHandler(_router);
// For running in containers, we respect the PORT environment variable.
final port = int.parse(Platform.environment['PORT'] ?? (useSecureConn ? '443' : '8080'));
final server = await serve(_handler, ip, port, securityContext: context);
print('Serving at http://${server.address.host}:${server.port}');
}
Questions
- There are three certificates issued (cert, fullchain, key), isn't
cert.pem
file necessary? If it is, how is it coded? - This server run fine on an unsecured protocol, i.e.:
http://mydomain.com:8080
, but is not working if I tryhttps://mydomain.com
, what's wrong? - Is
password: 'dartdart'
necessary forusePrivateKey
method? - What changes are needed for my server to work on a secure mode by using those certificates?