{"id":14468590,"url":"https://github.com/capturethesignal/cts-backend","last_synced_at":"2025-08-29T02:30:40.120Z","repository":{"id":97888797,"uuid":"379664096","full_name":"capturethesignal/cts-backend","owner":"capturethesignal","description":"Capture the Signal's backend tools and template challenge","archived":false,"fork":false,"pushed_at":"2021-07-06T10:13:26.000Z","size":198,"stargazers_count":7,"open_issues_count":0,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-12-26T05:32:01.497Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/capturethesignal.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-06-23T16:21:46.000Z","updated_at":"2024-09-27T14:27:47.000Z","dependencies_parsed_at":"2023-05-31T12:16:11.579Z","dependency_job_id":null,"html_url":"https://github.com/capturethesignal/cts-backend","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/capturethesignal/cts-backend","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/capturethesignal%2Fcts-backend","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/capturethesignal%2Fcts-backend/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/capturethesignal%2Fcts-backend/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/capturethesignal%2Fcts-backend/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/capturethesignal","download_url":"https://codeload.github.com/capturethesignal/cts-backend/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/capturethesignal%2Fcts-backend/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":272611534,"owners_count":24964380,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-29T02:00:10.610Z","response_time":87,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-09-02T03:04:36.339Z","updated_at":"2025-08-29T02:30:39.821Z","avatar_url":"https://github.com/capturethesignal.png","language":"Python","funding_links":[],"categories":["CTS Tools"],"sub_categories":["CTS server"],"readme":"# Capture the Signal' backend tools and template challenge\n\n- [Capture the Signal' backend tools and template challenge](#capture-the-signal-backend-tools-and-template-challenge)\n  - [Challenge Structure](#challenge-structure)\n  - [Development workflow](#development-workflow)\n  - [Running the Backend](#running-the-backend)\n  - [Docker Images](#docker-images)\n  - [Deployment on AWS](#deployment-on-aws)\n\nTo get started and create a **new edition of the CTS**, it's advisable to\ncreate a separate repo or branch to keeps things clean.\n\n```bash\n$ cp -R . /some/path/cts-EVENT_NAME\n$ cd /some/path/cts-EVENT_NAME\n$ git init\n```\n\nand continue from there. If you prefer working with branches, go with a new\nbranch!\n\n## Challenge Structure\n\nThis repository is intended for the team that runs the Capture the Signal, not\nfor release before each contest, unless you want to spoil the fun 😉\n\nIt contains the code to run the RF-over-IP server, in a dockerized fashion (one\nchallenge per container). Each challenge can be customized for each competition\nwithout rebuilding each docker image (although it'd take only a few seconds to\ndo).\n\nThe [cts-tools repository](https://github.com/capturethesignal/cts-tools)\ncontains instructions and material that can be handed out to the participants,\nyet only to the participants.\n\nThe `challenges/` folder in the present repository contains the challenge\nfiles, each in the following structure:\n\n* `cts-signal_\u003cN\u003e`:\n  - `bomb/` contains the GNURadio flowgraph\n    + `assets/` for any static file that you need to ship with your signal\n    + `requirements.pip` should you need signal-specific Python dependencies\n    + `main.sh` is the main that will be launched to run the signal\n    + `signal.grc` is the main flowgraph\n    + `Makefile` is used to compile the flowgraph into Python code `signal.py` (this should not be checked into the repository)\n    + `signal.cfg` is the configuration file referenced by the signal\n  - `README.md` please be nice, document your challenge\n\n## Development workflow\nTo create new signals, we suggest re-using existing ones. After all, as long as\nyou keep the same structure, it's just another GNURadio flowgraph to edit!\n\n1. Make a copy of a signal that is known to work\n    ```bash\n    $ cp -R cts-signal_0 cts-signal_\u003cN\u003e\n    $ cd cts-signal_\u003cN\u003e\n    ```\n2. Work on your `signal.grc` (e.g., using GNURadio Companion) and bare in mind\n   that everything should be self contained within the `signal_\u003cN\u003e` sub-folder.\n3. Test that your signal works well in GNURadio.\n\n## Running the Backend\nJust as easy as:\n\n```bash\n$ docker-compose up -d              # bring up ALL signals\n$ docker-compose ps\n$ docker-compose logs -f signal_0   # attach to signal_0 stdout\n\n$ docker-compose up signal_0        # bring up one signal and do not detach\n\n```\n\nNow you can test it by pointing it to the right virtual frequency (i.e., port).\n\n## Docker Images\nAll challenges develope so far can run on the `capturethesignal/cts-base`\nimage, which is based on `capturethesignal/gnuradio-mini-docker`. Both are\nhosted on the Docker Hub public registry:\n\n  * [docker.com/u/capturethesignal](https://hub.docker.com/u/capturethesignal)\n\nbut can be built locally if needed: check the [docker/](docker/) subfolder and the [phretor/gnuradio-mini-docker](https://github.com/phretor/gnuradio-mini-docker) repository.\n\n## Deployment on AWS\nWe've always been using AWS to deploy our CTS backends, but of course feel free to use whatever platform you prefer, and please keep this just as a reference. If you have enough time and are willing to share, the community would be enormously grateful to anyone who will send us a pull request with a Terraform script 😉\n\n* Computing\n  * Streaming RF over IP challenges\n    * 1 m5a.4xlarge instance size it depending on how many challenges/contestants will be receiving the streamed signals\n      * we suggest to deploy this in any of the public sub-networks, with all ports open\n      * have Docker and Docker Compose installed\n      * install AWS efs-utils to mount the `/var/challenges` EFS, to which you'll `git clone` this repository, and/or any other challenges that you're willing to run\n      * when AWS ECS will support port ranges, this instance could be replaced by a bunch of properly sized ECS tasks/containers\n  * Score board (based on CTFd)\n    * 1 Relational Database Service (RDS) database instance\n      * create an initial database named `ctfd`\n      * note the endpoint in the `DATABASE_URL` variable below\n      * has to support JSON data types: we use MariaDB \u003e= 10.4.18\n      * we haven't had [any success with using Amazon Aurora](https://github.com/CTFd/CTFd/issues/1936) although it [should support JSON data types](https://aws.amazon.com/blogs/database/using-json-with-mysql-5-7-compatible-amazon-aurora/)\n    * 1 ElastiCache Redis instance\n      * note the endpoint in the `REDIS_URL` below\n    * 1 Elastic File System (EFS) file system for persistent storage\n      * 1 EFS access point for the uploads (e.g., `/var/uploads`)\n      * 1 EFS access point for the logs (e.g., `/var/log/CTFd`)\n      * 1 EFS access point for the challenges\n    * 1 ECS (Elastic Container Service) Fargate cluster\n      * augment the default IAM role to include access to EFS\n      * 1 task definition\n        * 1 container pointing to the [ctfd/ctfd](https://hub.docker.com/r/ctfd/ctfd) Docker Image (or, feel free to use ours [capturethesignal/CTFd](https://hub.docker.com/r/capturethesignal/ctfd/))\n          * mount `/var/uploads` and `/var/log/CTFd` into the container and define at least these variables\n          * `ACCESS_LOG = -`\n          * `ERROR_LOG = -`\n          * `DATABASE_URL = mysql+pymysql://admin:CHANGEME@RDS_ENDPOINT.amazonaws.com/ctfd`\n          * `LOG_FOLDER = /var/log/CTFd`\n          * `UPLOAD_FOLDER = /var/uploads`\n          * `MAIL_USERNAME = YOUR_AWS_SES_SMTP_USER`\n          * `MAIL_PASSWORD = YOUR_AWS_SES_SMTP_PASS`\n          * `MAIL_PORT = 587`\n          * `MAIL_SERVER = YOUR_AWS_SES_SMTP_HOST`\n          * `MAIL_TLS = true`\n          * `MAIL_USEAUTH = true`\n          * `MAILFROM_ADDR = noreply@your.domain`\n          * `REDIS_URL = redis://ELASTICACHE_ENDPOINT.cache.amazonaws.com:6379`\n          * `REVERSE_PROXY = true`\n          * `SECRET_KEY = CHANGEME`\n          * `WORKERS = 4`\n          * more info at: https://docs.ctfd.io/docs/deployment/configuration/#server-level-configuration\n        * 1 service to run 1 instance of the task definition above\n          * the service needs to be associated a Security Group with 8000/tcp inbound rule allowed\n          * the service will receive HTTP requests from the ALB and will forward them to port 8000\n          * any time you'll restart or change the service, AWS ECS will re-configure the ALB automatically, so you won't need to change anything public facing\n  * Accessing the infrastructure\n    * 1 micro instance to debug, test, monitor, just in case\n      * we suggest to deploy this in any of the private sub-networks, with only port 22 open\n      * make this accessible from the outside via a TCP/IP network load balancer\n\n* Networking (use [this CloudFormation template](https://docs.aws.amazon.com/codebuild/latest/userguide/cloudformation-vpc-template.html))\n  * 1 VPC (Virtual Private Cloud)\n  * 1 Internet Gateway\n  * 2 NAT Gateways\n  * 2 Private sub-networks\n  * 2 Public sub-networks\n  * route tables\n  * 1 Application Load Balancer (ALB) to the scoreboard (use HTTPS if you can, ACM SSL certificates are free)\n  * 1 TCP/IP load balancer to the EC2 instance(s)\n  * (recommended) host your domain on Route 53 for ease of maintenance/integration\n  * make sure that you create enough security groups (SGs) and that machines/containers can reach each other, including (but not limited to):\n    * the EFS instance should have a SG configured with an inbound rule that allows traffic to NFS port (2049) from\n      * the 2 EC2 instances\n      * the ECS container\n    * the RDS instance should have a SG configured with an inbound rule that allows traffic to NFS port (2049) from the ECS container\n    * the Redis instance should have a SG configured with an inbound rule that allows traffic to Redis port (6379) from the ECS container\n    * the ECS task should be associated to a SG configured with inbound rules to allow traffic to port 8000/tcp (HTTP) from the ALB's SG\n\nWe're almost certain we've missed something 😇","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcapturethesignal%2Fcts-backend","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcapturethesignal%2Fcts-backend","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcapturethesignal%2Fcts-backend/lists"}