-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathbase.ts
93 lines (80 loc) · 2.97 KB
/
base.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
import { Peer, Port, SecurityGroup } from "aws-cdk-lib/aws-ec2";
import type { IPeer, SecurityGroupProps } from "aws-cdk-lib/aws-ec2";
import { GuAppAwareConstruct } from "../../../utils/mixin/app-aware-construct";
import type { AppIdentity, GuStack } from "../../core";
/**
* A way to describe an ingress or egress rule for a security group.
*
* See [[transformToSecurityGroupAccessRule]] for a handy helper function.
*/
export interface SecurityGroupAccessRule {
/**
* The CIDR address for this rule.
* Use `Peer.anyIpv4()` for global access.
*/
range: IPeer;
/**
* The port to open in a security group.
* The default protocol is TCP.
* Use `Port.udp(port)` for the UDP protocol.
*/
port: number | Port;
/**
* A short explanation for this rule.
*/
description: string;
}
export interface GuBaseSecurityGroupProps extends SecurityGroupProps {
ingresses?: SecurityGroupAccessRule[];
egresses?: SecurityGroupAccessRule[];
}
export interface GuSecurityGroupProps extends GuBaseSecurityGroupProps, AppIdentity {}
/**
* Defining an AWS Security Group with ingress and egress rules.
*
* An ingress rule on port 22 is strictly forbidden as SSH via SSM is preferred.
*
* Prefer to use a concrete implementation where possible. See:
* - [[GuWazuhAccess]]
* - [[GuPublicInternetAccessSecurityGroup]]
* - [[GuHttpsEgressSecurityGroup]]
*/
export class GuBaseSecurityGroup extends SecurityGroup {
constructor(scope: GuStack, id: string, props: GuBaseSecurityGroupProps) {
super(scope, id, props);
props.ingresses?.forEach(({ range, port, description }) => {
const connection: Port = typeof port === "number" ? Port.tcp(port) : port;
if (connection.toString() === "22") {
throw new Error("An ingress rule on port 22 is not allowed. Prefer to setup SSH via SSM.");
}
this.addIngressRule(range, connection, description);
});
props.egresses?.forEach(({ range, port, description }) => {
const connection: Port = typeof port === "number" ? Port.tcp(port) : port;
this.addEgressRule(range, connection, description);
});
}
}
export class GuSecurityGroup extends GuAppAwareConstruct(GuBaseSecurityGroup) {
constructor(scope: GuStack, id: string, props: GuSecurityGroupProps) {
super(scope, id, props);
}
}
/**
* Creates a security group which allows all outbound HTTPS traffic.
*/
// TODO should this be a singleton?
export class GuHttpsEgressSecurityGroup extends GuSecurityGroup {
constructor(scope: GuStack, id: string, props: GuSecurityGroupProps) {
super(scope, id, {
...props,
allowAllOutbound: false,
description: "Allow all outbound HTTPS traffic",
ingresses: [],
egresses: [{ range: Peer.anyIpv4(), port: 443, description: "Allow all outbound HTTPS traffic" }],
});
}
public static forVpc(scope: GuStack, props: GuSecurityGroupProps): GuHttpsEgressSecurityGroup {
return new GuHttpsEgressSecurityGroup(scope, "GuHttpsEgressSecurityGroup", props);
}
}