diff --git a/awx/main/tasks.py b/awx/main/tasks.py index aae882fa69..0deb9357aa 100644 --- a/awx/main/tasks.py +++ b/awx/main/tasks.py @@ -478,7 +478,10 @@ def inspect_execution_nodes(instance_list): for ad in connections: hostname = ad['NodeID'] commands = ad.get('WorkCommands') or [] - if 'ansible-runner' not in commands: + worktypes = [] + for c in commands: + worktypes.append(c["WorkType"]) + if 'ansible-runner' not in worktypes: continue changed = False if hostname in node_lookup: @@ -3053,7 +3056,7 @@ class AWXReceptorJob: use_stream_tls = get_conn_type(_kw['node'], receptor_ctl).name == "STREAMTLS" _kw['tlsclient'] = get_tls_client(use_stream_tls) - result = receptor_ctl.submit_work(worktype=self.work_type, payload=sockout.makefile('rb'), params=self.receptor_params, **_kw) + result = receptor_ctl.submit_work(worktype=self.work_type, payload=sockout.makefile('rb'), params=self.receptor_params, signwork=True, **_kw) self.unit_id = result['unitid'] self.task.update_model(self.task.instance.pk, work_unit_id=result['unitid']) diff --git a/awx/main/utils/receptor.py b/awx/main/utils/receptor.py index 404cee3577..0aa87e843c 100644 --- a/awx/main/utils/receptor.py +++ b/awx/main/utils/receptor.py @@ -70,6 +70,7 @@ def worker_info(node_name, work_type='ansible-runner'): kwargs = {} kwargs['tlsclient'] = get_tls_client(use_stream_tls) + kwargs['signwork'] = True if work_type != 'local': kwargs['ttl'] = '20s' result = receptor_ctl.submit_work(worktype=work_type, payload='', params={"params": f"--worker-info"}, node=node_name, **kwargs) diff --git a/tools/ansible/roles/dockerfile/templates/Dockerfile.j2 b/tools/ansible/roles/dockerfile/templates/Dockerfile.j2 index a8f53fe5c2..e8e27a2e82 100644 --- a/tools/ansible/roles/dockerfile/templates/Dockerfile.j2 +++ b/tools/ansible/roles/dockerfile/templates/Dockerfile.j2 @@ -166,7 +166,7 @@ COPY --from=builder /var/lib/awx /var/lib/awx RUN ln -s /var/lib/awx/venv/awx/bin/awx-manage /usr/bin/awx-manage {%if build_dev|bool %} -COPY --from=quay.io/project-receptor/receptor:1.0.0a2 /usr/bin/receptor /usr/bin/receptor +COPY --from=quay.io/ansible/receptor:devel /usr/bin/receptor /usr/bin/receptor RUN openssl req -nodes -newkey rsa:2048 -keyout /etc/nginx/nginx.key -out /etc/nginx/nginx.csr \ -subj "/C=US/ST=North Carolina/L=Durham/O=Ansible/OU=AWX Development/CN=awx.localhost" && \ openssl x509 -req -days 365 -in /etc/nginx/nginx.csr -signkey /etc/nginx/nginx.key -out /etc/nginx/nginx.crt && \ diff --git a/tools/docker-compose/ansible/roles/sources/defaults/main.yml b/tools/docker-compose/ansible/roles/sources/defaults/main.yml index 2e8cd25c4a..d6ab297f87 100644 --- a/tools/docker-compose/ansible/roles/sources/defaults/main.yml +++ b/tools/docker-compose/ansible/roles/sources/defaults/main.yml @@ -8,3 +8,10 @@ pg_database: 'awx' control_plane_node_count: 1 minikube_container_group: false receptor_socket_file: /var/run/awx-receptor/receptor.sock + +# Keys for signing work +receptor_rsa_bits: 4096 +receptor_work_sign_reconfigure: false +work_sign_key_dir: '../_sources/receptor' +work_sign_private_keyfile: "{{ work_sign_key_dir }}/work_private_key.pem" +work_sign_public_keyfile: "{{ work_sign_key_dir }}/work_public_key.pem" diff --git a/tools/docker-compose/ansible/roles/sources/tasks/main.yml b/tools/docker-compose/ansible/roles/sources/tasks/main.yml index 5d0d7170bb..b6df968ed7 100644 --- a/tools/docker-compose/ansible/roles/sources/tasks/main.yml +++ b/tools/docker-compose/ansible/roles/sources/tasks/main.yml @@ -79,6 +79,16 @@ awx_image_tag: "{{ lookup('file', playbook_dir + '/../../../VERSION') }}" when: awx_image_tag is not defined +- name: Generate Private RSA key for signing work + command: openssl genrsa -out {{ work_sign_private_keyfile }} {{ receptor_rsa_bits }} + args: + creates: "{{ work_sign_private_keyfile }}" + +- name: Generate public RSA key for signing work + command: openssl rsa -in {{ work_sign_private_keyfile }} -out {{ work_sign_public_keyfile }} -outform PEM -pubout + args: + creates: "{{ work_sign_public_keyfile }}" + - name: Render Docker-Compose template: src: docker-compose.yml.j2 diff --git a/tools/docker-compose/ansible/roles/sources/templates/docker-compose.yml.j2 b/tools/docker-compose/ansible/roles/sources/templates/docker-compose.yml.j2 index dbb4239f00..d623c82ef1 100644 --- a/tools/docker-compose/ansible/roles/sources/templates/docker-compose.yml.j2 +++ b/tools/docker-compose/ansible/roles/sources/templates/docker-compose.yml.j2 @@ -37,6 +37,8 @@ services: - "../../docker-compose/_sources/local_settings.py:/etc/tower/conf.d/local_settings.py" - "../../docker-compose/_sources/SECRET_KEY:/etc/tower/SECRET_KEY" - "../../docker-compose/_sources/receptor/receptor-awx-{{ loop.index }}.conf:/etc/receptor/receptor.conf" + - "../../docker-compose/_sources/receptor/work_public_key.pem:/etc/receptor/work_public_key.pem" + - "../../docker-compose/_sources/receptor/work_private_key.pem:/etc/receptor/work_private_key.pem" # - "../../docker-compose/_sources/certs:/etc/receptor/certs" # TODO: optionally generate certs - "/sys/fs/cgroup:/sys/fs/cgroup" - "~/.kube/config:/var/lib/awx/.kube/config" @@ -96,7 +98,7 @@ services: - "awx_db:/var/lib/postgresql/data" {% if execution_node_count|int > 0 %} receptor-hop: - image: quay.io/project-receptor/receptor:latest + image: quay.io/ansible/receptor:devel user: root container_name: tools_receptor_hop hostname: receptor-hop @@ -121,6 +123,7 @@ services: volumes: - "../../docker-compose/_sources/receptor/receptor-worker-{{ loop.index }}.conf:/etc/receptor/receptor.conf" - "/sys/fs/cgroup:/sys/fs/cgroup" + - "../../docker-compose/_sources/receptor/work_public_key.pem:/etc/receptor/work_public_key.pem" privileged: true {% endfor %} {% endif %} diff --git a/tools/docker-compose/ansible/roles/sources/templates/receptor-awx.conf.j2 b/tools/docker-compose/ansible/roles/sources/templates/receptor-awx.conf.j2 index c2d774d723..aba32d0e7f 100644 --- a/tools/docker-compose/ansible/roles/sources/templates/receptor-awx.conf.j2 +++ b/tools/docker-compose/ansible/roles/sources/templates/receptor-awx.conf.j2 @@ -1,12 +1,23 @@ --- - node: id: awx_{{ item }} + firewallrules: + - action: "reject" + tonode: awx_{{ item }} + toservice: "control" - log-level: info - tcp-listener: port: 2222 +- work-signing: + privatekey: /etc/receptor/work_private_key.pem + tokenexpiration: 1m + +- work-verification: + publickey: /etc/receptor/work_public_key.pem + {% for i in range(item | int + 1, control_plane_node_count | int + 1) %} - tcp-peer: address: awx_{{ i }}:2222 @@ -29,6 +40,7 @@ command: ansible-runner params: worker allowruntimeparams: true + verifysignature: true - work-kubernetes: worktype: kubernetes-runtime-auth @@ -36,6 +48,7 @@ allowruntimeauth: true allowruntimepod: true allowruntimeparams: true + verifysignature: true - work-kubernetes: worktype: kubernetes-incluster-auth @@ -43,3 +56,4 @@ allowruntimeauth: true allowruntimepod: true allowruntimeparams: true + verifysignature: true diff --git a/tools/docker-compose/ansible/roles/sources/templates/receptor-worker.conf.j2 b/tools/docker-compose/ansible/roles/sources/templates/receptor-worker.conf.j2 index 336f965982..1e2a6a47dc 100644 --- a/tools/docker-compose/ansible/roles/sources/templates/receptor-worker.conf.j2 +++ b/tools/docker-compose/ansible/roles/sources/templates/receptor-worker.conf.j2 @@ -8,11 +8,15 @@ address: tools_receptor_hop:5555 redial: true +- work-verification: + publickey: /etc/receptor/work_public_key.pem + - work-command: worktype: ansible-runner command: ansible-runner params: worker allowruntimeparams: true + verifysignature: true - control-service: service: control