commit fbd588721e5c6f78383db9487dc63f69a65472bf Author: Charlotte Croce Date: Sat Apr 19 23:42:08 2025 -0400 migrate to git.charlotte.sh diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..672296b --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +.vscode/ +.venv/ +__pycache__/ + +*.pickle +*.code-workspace \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..4002312 --- /dev/null +++ b/README.md @@ -0,0 +1,12 @@ +# Champlain College Tech Journals 🦫 +Notes, code, and lab write-ups from my Champlain College courses + +### CYBER +- [SEC350 - Network Security Controls](https://git.charlotte.sh/lotte/ChamplainTechJournals/src/branch/main/net-sec-controls-sec350) +- [SEC300 - Database Security (1-credit)](https://git.charlotte.sh/lotte/ChamplainTechJournals/src/branch/main/db-security-sec300) +### SYSADMIN +- [SYS255 - System Administration I](https://git.charlotte.sh/lotte/ChamplainTechJournals/src/branch/main/sysadmin-i-sys255) +- [SYS265 - System Administration II](https://git.charlotte.sh/lotte/ChamplainTechJournals/src/branch/main/sysadmin-ii-sys265) +- [SYS320 - Automation & Scripting](https://git.charlotte.sh/lotte/ChamplainTechJournals/src/branch/main/automation-sys320) +### COMPSCI +- [CSI160 - Python Programming](https://git.charlotte.sh/lotte/ChamplainTechJournals/src/branch/main/python-csi160) diff --git a/assets/01758254637888042610.png b/assets/01758254637888042610.png new file mode 100644 index 0000000..d247cc0 Binary files /dev/null and b/assets/01758254637888042610.png differ diff --git a/assets/0331dde8-2028-445d-89e2-d55fb5b3cf45.png b/assets/0331dde8-2028-445d-89e2-d55fb5b3cf45.png new file mode 100644 index 0000000..a1b8e18 Binary files /dev/null and b/assets/0331dde8-2028-445d-89e2-d55fb5b3cf45.png differ diff --git a/assets/03636611901023297692.png b/assets/03636611901023297692.png new file mode 100644 index 0000000..39e0bd9 Binary files /dev/null and b/assets/03636611901023297692.png differ diff --git a/assets/04857939417525985262.png b/assets/04857939417525985262.png new file mode 100644 index 0000000..83594f2 Binary files /dev/null and b/assets/04857939417525985262.png differ diff --git a/assets/05314847140022270031.png b/assets/05314847140022270031.png new file mode 100644 index 0000000..c146ac1 Binary files /dev/null and b/assets/05314847140022270031.png differ diff --git a/assets/06fa4ee7-ce28-40d2-8193-3f84b03b41d1.png b/assets/06fa4ee7-ce28-40d2-8193-3f84b03b41d1.png new file mode 100644 index 0000000..6f3d42d Binary files /dev/null and b/assets/06fa4ee7-ce28-40d2-8193-3f84b03b41d1.png differ diff --git a/assets/0dbd53ce-1e87-4aa7-8c4d-e592233d9f19.png b/assets/0dbd53ce-1e87-4aa7-8c4d-e592233d9f19.png new file mode 100644 index 0000000..3dc2721 Binary files /dev/null and b/assets/0dbd53ce-1e87-4aa7-8c4d-e592233d9f19.png differ diff --git a/assets/10871376959663845339.png b/assets/10871376959663845339.png new file mode 100644 index 0000000..386680b Binary files /dev/null and b/assets/10871376959663845339.png differ diff --git a/assets/12857208711233347105.png b/assets/12857208711233347105.png new file mode 100644 index 0000000..4180010 Binary files /dev/null and b/assets/12857208711233347105.png differ diff --git a/assets/143d58a5-5713-4425-b1d5-d8f9dcf63cf0.png b/assets/143d58a5-5713-4425-b1d5-d8f9dcf63cf0.png new file mode 100644 index 0000000..a5f62b7 Binary files /dev/null and b/assets/143d58a5-5713-4425-b1d5-d8f9dcf63cf0.png differ diff --git a/assets/1609a92a-ffe2-4d93-8477-f6669a95c2f5.png b/assets/1609a92a-ffe2-4d93-8477-f6669a95c2f5.png new file mode 100644 index 0000000..5c025b7 Binary files /dev/null and b/assets/1609a92a-ffe2-4d93-8477-f6669a95c2f5.png differ diff --git a/assets/16828656605260724970.png b/assets/16828656605260724970.png new file mode 100644 index 0000000..dad7f0a Binary files /dev/null and b/assets/16828656605260724970.png differ diff --git a/assets/19922310137972159113.png b/assets/19922310137972159113.png new file mode 100644 index 0000000..47658fa Binary files /dev/null and b/assets/19922310137972159113.png differ diff --git a/assets/19930188638651808078.png b/assets/19930188638651808078.png new file mode 100644 index 0000000..4deeb3c Binary files /dev/null and b/assets/19930188638651808078.png differ diff --git a/assets/1ae0ed12-ac5c-4a8a-bb70-cbfbe1b28a3a.png b/assets/1ae0ed12-ac5c-4a8a-bb70-cbfbe1b28a3a.png new file mode 100644 index 0000000..8dc82b6 Binary files /dev/null and b/assets/1ae0ed12-ac5c-4a8a-bb70-cbfbe1b28a3a.png differ diff --git a/assets/1b3f68db-04b0-42dc-837e-c9d0623132d4.png b/assets/1b3f68db-04b0-42dc-837e-c9d0623132d4.png new file mode 100644 index 0000000..3d6e93d Binary files /dev/null and b/assets/1b3f68db-04b0-42dc-837e-c9d0623132d4.png differ diff --git a/assets/1ea4dc4a-a2e4-4518-ae35-6ad320a8cf06.png b/assets/1ea4dc4a-a2e4-4518-ae35-6ad320a8cf06.png new file mode 100644 index 0000000..87636a5 Binary files /dev/null and b/assets/1ea4dc4a-a2e4-4518-ae35-6ad320a8cf06.png differ diff --git a/assets/1fc7982f-2d40-49d2-8264-356db5fb0d8c.png b/assets/1fc7982f-2d40-49d2-8264-356db5fb0d8c.png new file mode 100644 index 0000000..203cfb5 Binary files /dev/null and b/assets/1fc7982f-2d40-49d2-8264-356db5fb0d8c.png differ diff --git a/assets/24585442798448708938.png b/assets/24585442798448708938.png new file mode 100644 index 0000000..dad7f0a Binary files /dev/null and b/assets/24585442798448708938.png differ diff --git a/assets/24756578333294175972.png b/assets/24756578333294175972.png new file mode 100644 index 0000000..d2588c5 Binary files /dev/null and b/assets/24756578333294175972.png differ diff --git a/assets/25634b91-4a27-4ff5-a218-337fab157561.png b/assets/25634b91-4a27-4ff5-a218-337fab157561.png new file mode 100644 index 0000000..3ccce2e Binary files /dev/null and b/assets/25634b91-4a27-4ff5-a218-337fab157561.png differ diff --git a/assets/2629d201-965b-4a1e-8afe-7b88ebcbddd9.png b/assets/2629d201-965b-4a1e-8afe-7b88ebcbddd9.png new file mode 100644 index 0000000..53f595d Binary files /dev/null and b/assets/2629d201-965b-4a1e-8afe-7b88ebcbddd9.png differ diff --git a/assets/26917715998392128264.png b/assets/26917715998392128264.png new file mode 100644 index 0000000..28ec024 Binary files /dev/null and b/assets/26917715998392128264.png differ diff --git a/assets/26d035b6-8587-4277-ac33-3b4824459cc8.png b/assets/26d035b6-8587-4277-ac33-3b4824459cc8.png new file mode 100644 index 0000000..710a66c Binary files /dev/null and b/assets/26d035b6-8587-4277-ac33-3b4824459cc8.png differ diff --git a/assets/27e9470d-e84b-4e8b-8076-cfcbc9b54dea.png b/assets/27e9470d-e84b-4e8b-8076-cfcbc9b54dea.png new file mode 100644 index 0000000..26acccc Binary files /dev/null and b/assets/27e9470d-e84b-4e8b-8076-cfcbc9b54dea.png differ diff --git a/assets/28098970826352958907.png b/assets/28098970826352958907.png new file mode 100644 index 0000000..50d9d5c Binary files /dev/null and b/assets/28098970826352958907.png differ diff --git a/assets/28240178620173883519.png b/assets/28240178620173883519.png new file mode 100644 index 0000000..579513f Binary files /dev/null and b/assets/28240178620173883519.png differ diff --git a/assets/28558703339587372017.png b/assets/28558703339587372017.png new file mode 100644 index 0000000..c146ac1 Binary files /dev/null and b/assets/28558703339587372017.png differ diff --git a/assets/29390211350488594776.png b/assets/29390211350488594776.png new file mode 100644 index 0000000..baa21ff Binary files /dev/null and b/assets/29390211350488594776.png differ diff --git a/assets/2a087f38-8b59-4497-9162-1631205d0150.png b/assets/2a087f38-8b59-4497-9162-1631205d0150.png new file mode 100644 index 0000000..27f6d61 Binary files /dev/null and b/assets/2a087f38-8b59-4497-9162-1631205d0150.png differ diff --git a/assets/2a546cc0-a012-48b3-bfc8-3884334decfa.png b/assets/2a546cc0-a012-48b3-bfc8-3884334decfa.png new file mode 100644 index 0000000..bd2ef73 Binary files /dev/null and b/assets/2a546cc0-a012-48b3-bfc8-3884334decfa.png differ diff --git a/assets/2fe9dd01-e8e0-48c6-86a0-6f41fba39886.png b/assets/2fe9dd01-e8e0-48c6-86a0-6f41fba39886.png new file mode 100644 index 0000000..4df8d5b Binary files /dev/null and b/assets/2fe9dd01-e8e0-48c6-86a0-6f41fba39886.png differ diff --git a/assets/30721057773960504326.png b/assets/30721057773960504326.png new file mode 100644 index 0000000..f6dcbe7 Binary files /dev/null and b/assets/30721057773960504326.png differ diff --git a/assets/31513948136685754208.png b/assets/31513948136685754208.png new file mode 100644 index 0000000..f6dcbe7 Binary files /dev/null and b/assets/31513948136685754208.png differ diff --git a/assets/33901315023577898721.png b/assets/33901315023577898721.png new file mode 100644 index 0000000..8010393 Binary files /dev/null and b/assets/33901315023577898721.png differ diff --git a/assets/33943375160707739844.png b/assets/33943375160707739844.png new file mode 100644 index 0000000..c146ac1 Binary files /dev/null and b/assets/33943375160707739844.png differ diff --git a/assets/37176438071902029052.png b/assets/37176438071902029052.png new file mode 100644 index 0000000..ba81cac Binary files /dev/null and b/assets/37176438071902029052.png differ diff --git a/assets/37730256050044103788.png b/assets/37730256050044103788.png new file mode 100644 index 0000000..ed5acab Binary files /dev/null and b/assets/37730256050044103788.png differ diff --git a/assets/37f2c335-0611-42c9-962a-62a4681eeae5.png b/assets/37f2c335-0611-42c9-962a-62a4681eeae5.png new file mode 100644 index 0000000..f3ef02d Binary files /dev/null and b/assets/37f2c335-0611-42c9-962a-62a4681eeae5.png differ diff --git a/assets/38151840315337592533.png b/assets/38151840315337592533.png new file mode 100644 index 0000000..ed5acab Binary files /dev/null and b/assets/38151840315337592533.png differ diff --git a/assets/383fc178-8815-4a57-90f3-7138d8bbf02b.png b/assets/383fc178-8815-4a57-90f3-7138d8bbf02b.png new file mode 100644 index 0000000..6e2b515 Binary files /dev/null and b/assets/383fc178-8815-4a57-90f3-7138d8bbf02b.png differ diff --git a/assets/38e9d23f-a37a-4e61-948c-b949cbb19acc.png b/assets/38e9d23f-a37a-4e61-948c-b949cbb19acc.png new file mode 100644 index 0000000..04871f5 Binary files /dev/null and b/assets/38e9d23f-a37a-4e61-948c-b949cbb19acc.png differ diff --git a/assets/39189716510044144776.png b/assets/39189716510044144776.png new file mode 100644 index 0000000..73065c4 Binary files /dev/null and b/assets/39189716510044144776.png differ diff --git a/assets/3b863e99-1ae4-4d29-91cb-1a3b187aab5f.png b/assets/3b863e99-1ae4-4d29-91cb-1a3b187aab5f.png new file mode 100644 index 0000000..16d2e17 Binary files /dev/null and b/assets/3b863e99-1ae4-4d29-91cb-1a3b187aab5f.png differ diff --git a/assets/40d632c5-18c8-42b0-a938-19f6aabce1d0.png b/assets/40d632c5-18c8-42b0-a938-19f6aabce1d0.png new file mode 100644 index 0000000..68a0acf Binary files /dev/null and b/assets/40d632c5-18c8-42b0-a938-19f6aabce1d0.png differ diff --git a/assets/43771867875812711176.png b/assets/43771867875812711176.png new file mode 100644 index 0000000..7c32432 Binary files /dev/null and b/assets/43771867875812711176.png differ diff --git a/assets/43941698123959225528.png b/assets/43941698123959225528.png new file mode 100644 index 0000000..7c32432 Binary files /dev/null and b/assets/43941698123959225528.png differ diff --git a/assets/45ad5e35-665c-4861-a8be-e9aa17d6b676.png b/assets/45ad5e35-665c-4861-a8be-e9aa17d6b676.png new file mode 100644 index 0000000..aba9575 Binary files /dev/null and b/assets/45ad5e35-665c-4861-a8be-e9aa17d6b676.png differ diff --git a/assets/46252357-1387-45bd-a4ae-ede9e12417c9.png b/assets/46252357-1387-45bd-a4ae-ede9e12417c9.png new file mode 100644 index 0000000..5cd0c9b Binary files /dev/null and b/assets/46252357-1387-45bd-a4ae-ede9e12417c9.png differ diff --git a/assets/46328876421707075218.png b/assets/46328876421707075218.png new file mode 100644 index 0000000..47a0873 Binary files /dev/null and b/assets/46328876421707075218.png differ diff --git a/assets/48048756981632248005.png b/assets/48048756981632248005.png new file mode 100644 index 0000000..6d4aeae Binary files /dev/null and b/assets/48048756981632248005.png differ diff --git a/assets/48994d9b-0f17-4626-ab9d-985d37c5e506.png b/assets/48994d9b-0f17-4626-ab9d-985d37c5e506.png new file mode 100644 index 0000000..0ff1833 Binary files /dev/null and b/assets/48994d9b-0f17-4626-ab9d-985d37c5e506.png differ diff --git a/assets/49334009375200079531.png b/assets/49334009375200079531.png new file mode 100644 index 0000000..e48f447 Binary files /dev/null and b/assets/49334009375200079531.png differ diff --git a/assets/4b9ac768-72f6-4ef4-92ed-5be231e63c7b.png b/assets/4b9ac768-72f6-4ef4-92ed-5be231e63c7b.png new file mode 100644 index 0000000..0475398 Binary files /dev/null and b/assets/4b9ac768-72f6-4ef4-92ed-5be231e63c7b.png differ diff --git a/assets/4df08b6e-cbf7-474b-8301-f2f52e65ba4d.png b/assets/4df08b6e-cbf7-474b-8301-f2f52e65ba4d.png new file mode 100644 index 0000000..a87382e Binary files /dev/null and b/assets/4df08b6e-cbf7-474b-8301-f2f52e65ba4d.png differ diff --git a/assets/500def07-6fb1-4fb5-82a8-4c4f433e3861.png b/assets/500def07-6fb1-4fb5-82a8-4c4f433e3861.png new file mode 100644 index 0000000..39da1c6 Binary files /dev/null and b/assets/500def07-6fb1-4fb5-82a8-4c4f433e3861.png differ diff --git a/assets/52008438397585002082.png b/assets/52008438397585002082.png new file mode 100644 index 0000000..d2b3593 Binary files /dev/null and b/assets/52008438397585002082.png differ diff --git a/assets/53438651249532045143.png b/assets/53438651249532045143.png new file mode 100644 index 0000000..f614223 Binary files /dev/null and b/assets/53438651249532045143.png differ diff --git a/assets/545f45bb-c125-4f69-9447-b605773f26be.png b/assets/545f45bb-c125-4f69-9447-b605773f26be.png new file mode 100644 index 0000000..bc44200 Binary files /dev/null and b/assets/545f45bb-c125-4f69-9447-b605773f26be.png differ diff --git a/assets/54a8264b-ffac-4f98-be7d-5d1abce24233.png b/assets/54a8264b-ffac-4f98-be7d-5d1abce24233.png new file mode 100644 index 0000000..da368dc Binary files /dev/null and b/assets/54a8264b-ffac-4f98-be7d-5d1abce24233.png differ diff --git a/assets/57c507d3-202d-4f0b-a19e-3da3bf8f3450.png b/assets/57c507d3-202d-4f0b-a19e-3da3bf8f3450.png new file mode 100644 index 0000000..ec8013f Binary files /dev/null and b/assets/57c507d3-202d-4f0b-a19e-3da3bf8f3450.png differ diff --git a/assets/57d3e4d5-2d74-45c7-91e1-7e0066bcaf10.png b/assets/57d3e4d5-2d74-45c7-91e1-7e0066bcaf10.png new file mode 100644 index 0000000..af19d95 Binary files /dev/null and b/assets/57d3e4d5-2d74-45c7-91e1-7e0066bcaf10.png differ diff --git a/assets/58172189251604865478.png b/assets/58172189251604865478.png new file mode 100644 index 0000000..d8270dc Binary files /dev/null and b/assets/58172189251604865478.png differ diff --git a/assets/58672890206317596780.png b/assets/58672890206317596780.png new file mode 100644 index 0000000..7d7384c Binary files /dev/null and b/assets/58672890206317596780.png differ diff --git a/assets/59be1bd2-d915-4360-9595-f0d32d68e030.png b/assets/59be1bd2-d915-4360-9595-f0d32d68e030.png new file mode 100644 index 0000000..a55ad00 Binary files /dev/null and b/assets/59be1bd2-d915-4360-9595-f0d32d68e030.png differ diff --git a/assets/5bde20db-9f06-4891-b5f1-22cea0ab2014.png b/assets/5bde20db-9f06-4891-b5f1-22cea0ab2014.png new file mode 100644 index 0000000..966209e Binary files /dev/null and b/assets/5bde20db-9f06-4891-b5f1-22cea0ab2014.png differ diff --git a/assets/5e739863-3710-4ea0-8988-2a9c56ddb981.png b/assets/5e739863-3710-4ea0-8988-2a9c56ddb981.png new file mode 100644 index 0000000..b126aab Binary files /dev/null and b/assets/5e739863-3710-4ea0-8988-2a9c56ddb981.png differ diff --git a/assets/62052853300074043448.png b/assets/62052853300074043448.png new file mode 100644 index 0000000..51bbd25 Binary files /dev/null and b/assets/62052853300074043448.png differ diff --git a/assets/62b95926-6b2a-42e2-a12f-610b1a3336b8.png b/assets/62b95926-6b2a-42e2-a12f-610b1a3336b8.png new file mode 100644 index 0000000..fe36171 Binary files /dev/null and b/assets/62b95926-6b2a-42e2-a12f-610b1a3336b8.png differ diff --git a/assets/63700441181267143731.png b/assets/63700441181267143731.png new file mode 100644 index 0000000..e435270 Binary files /dev/null and b/assets/63700441181267143731.png differ diff --git a/assets/64154464512101878437.png b/assets/64154464512101878437.png new file mode 100644 index 0000000..b379bc1 Binary files /dev/null and b/assets/64154464512101878437.png differ diff --git a/assets/64d738b7-1b8e-45ea-9f7d-474fc6679cfb.png b/assets/64d738b7-1b8e-45ea-9f7d-474fc6679cfb.png new file mode 100644 index 0000000..3e58154 Binary files /dev/null and b/assets/64d738b7-1b8e-45ea-9f7d-474fc6679cfb.png differ diff --git a/assets/67134300422837141517.png b/assets/67134300422837141517.png new file mode 100644 index 0000000..e31941b Binary files /dev/null and b/assets/67134300422837141517.png differ diff --git a/assets/67257474633139373020.png b/assets/67257474633139373020.png new file mode 100644 index 0000000..8005ad8 Binary files /dev/null and b/assets/67257474633139373020.png differ diff --git a/assets/68338520046570456579.png b/assets/68338520046570456579.png new file mode 100644 index 0000000..9da0edf Binary files /dev/null and b/assets/68338520046570456579.png differ diff --git a/assets/68759560798920867956.png b/assets/68759560798920867956.png new file mode 100644 index 0000000..1d66c81 Binary files /dev/null and b/assets/68759560798920867956.png differ diff --git a/assets/68f108b9-2a62-4575-9614-c2ec286093ad.png b/assets/68f108b9-2a62-4575-9614-c2ec286093ad.png new file mode 100644 index 0000000..dcdc4bb Binary files /dev/null and b/assets/68f108b9-2a62-4575-9614-c2ec286093ad.png differ diff --git a/assets/723c16dc-f130-4f61-9508-b0fe70adbca5.png b/assets/723c16dc-f130-4f61-9508-b0fe70adbca5.png new file mode 100644 index 0000000..68996ce Binary files /dev/null and b/assets/723c16dc-f130-4f61-9508-b0fe70adbca5.png differ diff --git a/assets/72455756211919931734.png b/assets/72455756211919931734.png new file mode 100644 index 0000000..06ef249 Binary files /dev/null and b/assets/72455756211919931734.png differ diff --git a/assets/72766234477222890914.png b/assets/72766234477222890914.png new file mode 100644 index 0000000..47658fa Binary files /dev/null and b/assets/72766234477222890914.png differ diff --git a/assets/727824d9-510f-4235-8e62-7360a41ebae2.png b/assets/727824d9-510f-4235-8e62-7360a41ebae2.png new file mode 100644 index 0000000..f854b1e Binary files /dev/null and b/assets/727824d9-510f-4235-8e62-7360a41ebae2.png differ diff --git a/assets/73076712-88fa-4c39-866b-da138c52002d.png b/assets/73076712-88fa-4c39-866b-da138c52002d.png new file mode 100644 index 0000000..ee4a39f Binary files /dev/null and b/assets/73076712-88fa-4c39-866b-da138c52002d.png differ diff --git a/assets/74084820811547432549.png b/assets/74084820811547432549.png new file mode 100644 index 0000000..d3ba611 Binary files /dev/null and b/assets/74084820811547432549.png differ diff --git a/assets/742df745-1a26-4c6d-a082-d7edfa04fd2f.png b/assets/742df745-1a26-4c6d-a082-d7edfa04fd2f.png new file mode 100644 index 0000000..b415f8a Binary files /dev/null and b/assets/742df745-1a26-4c6d-a082-d7edfa04fd2f.png differ diff --git a/assets/74799811371189113438.png b/assets/74799811371189113438.png new file mode 100644 index 0000000..1676ce9 Binary files /dev/null and b/assets/74799811371189113438.png differ diff --git a/assets/75917456384225415742.png b/assets/75917456384225415742.png new file mode 100644 index 0000000..2b47126 Binary files /dev/null and b/assets/75917456384225415742.png differ diff --git a/assets/75972885183370410713.png b/assets/75972885183370410713.png new file mode 100644 index 0000000..823b5c8 Binary files /dev/null and b/assets/75972885183370410713.png differ diff --git a/assets/76304685-062f-41df-ac18-092174428aa2.png b/assets/76304685-062f-41df-ac18-092174428aa2.png new file mode 100644 index 0000000..50b807a Binary files /dev/null and b/assets/76304685-062f-41df-ac18-092174428aa2.png differ diff --git a/assets/77c2b1f5-6aa2-4e76-8db6-59feb31cb4fb.png b/assets/77c2b1f5-6aa2-4e76-8db6-59feb31cb4fb.png new file mode 100644 index 0000000..23df339 Binary files /dev/null and b/assets/77c2b1f5-6aa2-4e76-8db6-59feb31cb4fb.png differ diff --git a/assets/78542122222727064667.png b/assets/78542122222727064667.png new file mode 100644 index 0000000..e363fb3 Binary files /dev/null and b/assets/78542122222727064667.png differ diff --git a/assets/79433639441373818146.png b/assets/79433639441373818146.png new file mode 100644 index 0000000..d247cc0 Binary files /dev/null and b/assets/79433639441373818146.png differ diff --git a/assets/79934145188703508417.png b/assets/79934145188703508417.png new file mode 100644 index 0000000..d24cb8d Binary files /dev/null and b/assets/79934145188703508417.png differ diff --git a/assets/79939807685859687080.png b/assets/79939807685859687080.png new file mode 100644 index 0000000..624d105 Binary files /dev/null and b/assets/79939807685859687080.png differ diff --git a/assets/7a571e73-76f3-4efe-a4dd-644c0c856011.png b/assets/7a571e73-76f3-4efe-a4dd-644c0c856011.png new file mode 100644 index 0000000..40fd24f Binary files /dev/null and b/assets/7a571e73-76f3-4efe-a4dd-644c0c856011.png differ diff --git a/assets/82622175695437562641.png b/assets/82622175695437562641.png new file mode 100644 index 0000000..f2d0109 Binary files /dev/null and b/assets/82622175695437562641.png differ diff --git a/assets/83024217931244774671.png b/assets/83024217931244774671.png new file mode 100644 index 0000000..6d4aeae Binary files /dev/null and b/assets/83024217931244774671.png differ diff --git a/assets/86616956786813358962.png b/assets/86616956786813358962.png new file mode 100644 index 0000000..8a0e8a7 Binary files /dev/null and b/assets/86616956786813358962.png differ diff --git a/assets/86790690807473581275.png b/assets/86790690807473581275.png new file mode 100644 index 0000000..4cdceb4 Binary files /dev/null and b/assets/86790690807473581275.png differ diff --git a/assets/88267494287421380633.png b/assets/88267494287421380633.png new file mode 100644 index 0000000..3bd3933 Binary files /dev/null and b/assets/88267494287421380633.png differ diff --git a/assets/8c9e506d-5da1-4907-8773-2ef2dc7cd53b.png b/assets/8c9e506d-5da1-4907-8773-2ef2dc7cd53b.png new file mode 100644 index 0000000..c1b5a3e Binary files /dev/null and b/assets/8c9e506d-5da1-4907-8773-2ef2dc7cd53b.png differ diff --git a/assets/8ed3b550-988b-432c-895e-3f1e3acceb45.png b/assets/8ed3b550-988b-432c-895e-3f1e3acceb45.png new file mode 100644 index 0000000..1e24ff7 Binary files /dev/null and b/assets/8ed3b550-988b-432c-895e-3f1e3acceb45.png differ diff --git a/assets/91567249402275548007.png b/assets/91567249402275548007.png new file mode 100644 index 0000000..8005ad8 Binary files /dev/null and b/assets/91567249402275548007.png differ diff --git a/assets/91933866224254504914.png b/assets/91933866224254504914.png new file mode 100644 index 0000000..7c32432 Binary files /dev/null and b/assets/91933866224254504914.png differ diff --git a/assets/92898586767705871114.png b/assets/92898586767705871114.png new file mode 100644 index 0000000..2cae71f Binary files /dev/null and b/assets/92898586767705871114.png differ diff --git a/assets/94903686988792799224.png b/assets/94903686988792799224.png new file mode 100644 index 0000000..e435270 Binary files /dev/null and b/assets/94903686988792799224.png differ diff --git a/assets/95617902500355142510.png b/assets/95617902500355142510.png new file mode 100644 index 0000000..69d2934 Binary files /dev/null and b/assets/95617902500355142510.png differ diff --git a/assets/95767524973765505119.png b/assets/95767524973765505119.png new file mode 100644 index 0000000..3a9f25e Binary files /dev/null and b/assets/95767524973765505119.png differ diff --git a/assets/9587f614-c944-4943-9d33-aedb0e477008.png b/assets/9587f614-c944-4943-9d33-aedb0e477008.png new file mode 100644 index 0000000..ac9c70c Binary files /dev/null and b/assets/9587f614-c944-4943-9d33-aedb0e477008.png differ diff --git a/assets/97855147798409096157.png b/assets/97855147798409096157.png new file mode 100644 index 0000000..f87cd1c Binary files /dev/null and b/assets/97855147798409096157.png differ diff --git a/assets/98848962126250929641.png b/assets/98848962126250929641.png new file mode 100644 index 0000000..9428433 Binary files /dev/null and b/assets/98848962126250929641.png differ diff --git a/assets/99368313498985658442.png b/assets/99368313498985658442.png new file mode 100644 index 0000000..58f5860 Binary files /dev/null and b/assets/99368313498985658442.png differ diff --git a/assets/9f753b28-fd3b-4854-b155-54bca96e239c.png b/assets/9f753b28-fd3b-4854-b155-54bca96e239c.png new file mode 100644 index 0000000..6c654db Binary files /dev/null and b/assets/9f753b28-fd3b-4854-b155-54bca96e239c.png differ diff --git a/assets/a2abea31-7eb8-486a-b563-3962d086ab44.png b/assets/a2abea31-7eb8-486a-b563-3962d086ab44.png new file mode 100644 index 0000000..2e543b1 Binary files /dev/null and b/assets/a2abea31-7eb8-486a-b563-3962d086ab44.png differ diff --git a/assets/a51c6beb-41a7-4885-a285-61885f073995.png b/assets/a51c6beb-41a7-4885-a285-61885f073995.png new file mode 100644 index 0000000..f2acc76 Binary files /dev/null and b/assets/a51c6beb-41a7-4885-a285-61885f073995.png differ diff --git a/assets/a5a9d811-0e27-48e2-b25d-97cb9e345e56.png b/assets/a5a9d811-0e27-48e2-b25d-97cb9e345e56.png new file mode 100644 index 0000000..739f2d3 Binary files /dev/null and b/assets/a5a9d811-0e27-48e2-b25d-97cb9e345e56.png differ diff --git a/assets/aa578b16-2113-4af0-b7c7-ae18e52ad336.png b/assets/aa578b16-2113-4af0-b7c7-ae18e52ad336.png new file mode 100644 index 0000000..1f6ffa1 Binary files /dev/null and b/assets/aa578b16-2113-4af0-b7c7-ae18e52ad336.png differ diff --git a/assets/b295e94c-3da4-4dbe-98d5-45f25a4da00a.png b/assets/b295e94c-3da4-4dbe-98d5-45f25a4da00a.png new file mode 100644 index 0000000..4c69fdb Binary files /dev/null and b/assets/b295e94c-3da4-4dbe-98d5-45f25a4da00a.png differ diff --git a/assets/b42fc4c4-07fe-44e1-ae48-59a1ea275408.png b/assets/b42fc4c4-07fe-44e1-ae48-59a1ea275408.png new file mode 100644 index 0000000..885ae04 Binary files /dev/null and b/assets/b42fc4c4-07fe-44e1-ae48-59a1ea275408.png differ diff --git a/assets/b60a950e-bc09-424d-93cc-38c55deb0105.png b/assets/b60a950e-bc09-424d-93cc-38c55deb0105.png new file mode 100644 index 0000000..8f5f20d Binary files /dev/null and b/assets/b60a950e-bc09-424d-93cc-38c55deb0105.png differ diff --git a/assets/b7112a43-e0e0-4d8c-af36-a7a925ccc1d8.png b/assets/b7112a43-e0e0-4d8c-af36-a7a925ccc1d8.png new file mode 100644 index 0000000..5128f0b Binary files /dev/null and b/assets/b7112a43-e0e0-4d8c-af36-a7a925ccc1d8.png differ diff --git a/assets/b752ce4c-f831-4619-b563-9a2ff9eb57c5.png b/assets/b752ce4c-f831-4619-b563-9a2ff9eb57c5.png new file mode 100644 index 0000000..d7e7a4a Binary files /dev/null and b/assets/b752ce4c-f831-4619-b563-9a2ff9eb57c5.png differ diff --git a/assets/b7c9efbf-0819-4381-99f7-14826220bb8a.png b/assets/b7c9efbf-0819-4381-99f7-14826220bb8a.png new file mode 100644 index 0000000..5e10845 Binary files /dev/null and b/assets/b7c9efbf-0819-4381-99f7-14826220bb8a.png differ diff --git a/assets/bb0207b1-5010-4d36-9fdd-028ec450cc5e.png b/assets/bb0207b1-5010-4d36-9fdd-028ec450cc5e.png new file mode 100644 index 0000000..cfd8894 Binary files /dev/null and b/assets/bb0207b1-5010-4d36-9fdd-028ec450cc5e.png differ diff --git a/assets/bcdeb3dd-1245-4fc0-aff3-0a84cb383c8f.png b/assets/bcdeb3dd-1245-4fc0-aff3-0a84cb383c8f.png new file mode 100644 index 0000000..4fd1681 Binary files /dev/null and b/assets/bcdeb3dd-1245-4fc0-aff3-0a84cb383c8f.png differ diff --git a/assets/c12ab0af-4ef2-4904-9ede-9d4d96a65122.png b/assets/c12ab0af-4ef2-4904-9ede-9d4d96a65122.png new file mode 100644 index 0000000..692ec89 Binary files /dev/null and b/assets/c12ab0af-4ef2-4904-9ede-9d4d96a65122.png differ diff --git a/assets/c2924ebd-c975-4cbf-9b0e-b26e36954fdb.png b/assets/c2924ebd-c975-4cbf-9b0e-b26e36954fdb.png new file mode 100644 index 0000000..1beeba1 Binary files /dev/null and b/assets/c2924ebd-c975-4cbf-9b0e-b26e36954fdb.png differ diff --git a/assets/c69680f9-be75-4b5e-976b-cf6b508f6553.png b/assets/c69680f9-be75-4b5e-976b-cf6b508f6553.png new file mode 100644 index 0000000..0511b2f Binary files /dev/null and b/assets/c69680f9-be75-4b5e-976b-cf6b508f6553.png differ diff --git a/assets/c6c6ae88-635e-4db1-a1d3-e1473bf63653.png b/assets/c6c6ae88-635e-4db1-a1d3-e1473bf63653.png new file mode 100644 index 0000000..c50ad8c Binary files /dev/null and b/assets/c6c6ae88-635e-4db1-a1d3-e1473bf63653.png differ diff --git a/assets/c921d829-5bc4-4048-a4fb-de42b1f413a7.png b/assets/c921d829-5bc4-4048-a4fb-de42b1f413a7.png new file mode 100644 index 0000000..7d3187d Binary files /dev/null and b/assets/c921d829-5bc4-4048-a4fb-de42b1f413a7.png differ diff --git a/assets/cb27b4f7-abd2-489e-a465-fadf7005c57a.png b/assets/cb27b4f7-abd2-489e-a465-fadf7005c57a.png new file mode 100644 index 0000000..1a2c7ef Binary files /dev/null and b/assets/cb27b4f7-abd2-489e-a465-fadf7005c57a.png differ diff --git a/assets/cd26c18f-74b8-481c-bc37-8c602f7f46c7.png b/assets/cd26c18f-74b8-481c-bc37-8c602f7f46c7.png new file mode 100644 index 0000000..9e0f155 Binary files /dev/null and b/assets/cd26c18f-74b8-481c-bc37-8c602f7f46c7.png differ diff --git a/assets/d750c565-6a8c-4867-8da3-949046bb5a1e.png b/assets/d750c565-6a8c-4867-8da3-949046bb5a1e.png new file mode 100644 index 0000000..206238d Binary files /dev/null and b/assets/d750c565-6a8c-4867-8da3-949046bb5a1e.png differ diff --git a/assets/dccadcee-10f4-4fce-ac7b-0f7b9b87f0cd.png b/assets/dccadcee-10f4-4fce-ac7b-0f7b9b87f0cd.png new file mode 100644 index 0000000..17bd050 Binary files /dev/null and b/assets/dccadcee-10f4-4fce-ac7b-0f7b9b87f0cd.png differ diff --git a/assets/e7adaa35-9aaa-4f0c-8a93-4f4ded361027.png b/assets/e7adaa35-9aaa-4f0c-8a93-4f4ded361027.png new file mode 100644 index 0000000..d8d87e6 Binary files /dev/null and b/assets/e7adaa35-9aaa-4f0c-8a93-4f4ded361027.png differ diff --git a/assets/e8491101-e466-4046-be31-eb397ee2f159.png b/assets/e8491101-e466-4046-be31-eb397ee2f159.png new file mode 100644 index 0000000..fe4c1e8 Binary files /dev/null and b/assets/e8491101-e466-4046-be31-eb397ee2f159.png differ diff --git a/assets/e9fe5785-ef2b-4efa-9cc2-f10c25cc9476.png b/assets/e9fe5785-ef2b-4efa-9cc2-f10c25cc9476.png new file mode 100644 index 0000000..c9b90fe Binary files /dev/null and b/assets/e9fe5785-ef2b-4efa-9cc2-f10c25cc9476.png differ diff --git a/assets/f1b9d632-2664-4209-beae-3ee167b93a76.png b/assets/f1b9d632-2664-4209-beae-3ee167b93a76.png new file mode 100644 index 0000000..4bd7153 Binary files /dev/null and b/assets/f1b9d632-2664-4209-beae-3ee167b93a76.png differ diff --git a/assets/f45b745c-6aff-4cd6-86dd-0ddb13256267.png b/assets/f45b745c-6aff-4cd6-86dd-0ddb13256267.png new file mode 100644 index 0000000..02ab1dd Binary files /dev/null and b/assets/f45b745c-6aff-4cd6-86dd-0ddb13256267.png differ diff --git a/assets/f62408cf-24bd-4947-9277-df5637f800e5.png b/assets/f62408cf-24bd-4947-9277-df5637f800e5.png new file mode 100644 index 0000000..d47ef5d Binary files /dev/null and b/assets/f62408cf-24bd-4947-9277-df5637f800e5.png differ diff --git a/assets/f6c94f07-746a-4cc1-8f09-db5eb76f08a5.png b/assets/f6c94f07-746a-4cc1-8f09-db5eb76f08a5.png new file mode 100644 index 0000000..13e2651 Binary files /dev/null and b/assets/f6c94f07-746a-4cc1-8f09-db5eb76f08a5.png differ diff --git a/assets/f7c0d739-296c-4fab-96b2-4afe4439aee6.png b/assets/f7c0d739-296c-4fab-96b2-4afe4439aee6.png new file mode 100644 index 0000000..738d0aa Binary files /dev/null and b/assets/f7c0d739-296c-4fab-96b2-4afe4439aee6.png differ diff --git a/assets/fd5cfed4-9f89-46ea-82e9-e5f8f593a8c2.png b/assets/fd5cfed4-9f89-46ea-82e9-e5f8f593a8c2.png new file mode 100644 index 0000000..c5bf801 Binary files /dev/null and b/assets/fd5cfed4-9f89-46ea-82e9-e5f8f593a8c2.png differ diff --git a/assets/fee62fbf-d5a3-4564-a8a4-2c09ee5e3a9e.png b/assets/fee62fbf-d5a3-4564-a8a4-2c09ee5e3a9e.png new file mode 100644 index 0000000..39db73a Binary files /dev/null and b/assets/fee62fbf-d5a3-4564-a8a4-2c09ee5e3a9e.png differ diff --git a/assets/formaction.png b/assets/formaction.png new file mode 100644 index 0000000..9d949e5 Binary files /dev/null and b/assets/formaction.png differ diff --git a/assets/lab04sys255.png b/assets/lab04sys255.png new file mode 100644 index 0000000..61c4322 Binary files /dev/null and b/assets/lab04sys255.png differ diff --git a/assets/lab05-1.png b/assets/lab05-1.png new file mode 100644 index 0000000..0025cff Binary files /dev/null and b/assets/lab05-1.png differ diff --git a/assets/lab07-1.png b/assets/lab07-1.png new file mode 100644 index 0000000..be98f5a Binary files /dev/null and b/assets/lab07-1.png differ diff --git a/assets/wordpress.png b/assets/wordpress.png new file mode 100644 index 0000000..4ad1471 Binary files /dev/null and b/assets/wordpress.png differ diff --git a/automation-sys320/README.md b/automation-sys320/README.md new file mode 100644 index 0000000..e84559d --- /dev/null +++ b/automation-sys320/README.md @@ -0,0 +1,19 @@ +# Automation and Scripting +Fall 2024 +## Powershell +- [week01](https://git.charlotte.sh/lotte/ChamplainTechJournals/src/branch/main/automation-sys320/week01): Introduction +- [week02](https://git.charlotte.sh/lotte/ChamplainTechJournals/src/branch/main/automation-sys320/week02): Cmdlets and Members +- [week03](https://git.charlotte.sh/lotte/ChamplainTechJournals/src/branch/main/automation-sys320/week03): Flow Control +- [week04](https://git.charlotte.sh/lotte/ChamplainTechJournals/src/branch/main/automation-sys320/week04): Access to File Content +- [week05](https://git.charlotte.sh/lotte/ChamplainTechJournals/src/branch/main/automation-sys320/week05): Web Scraping +- [week06](https://git.charlotte.sh/lotte/ChamplainTechJournals/src/branch/main/automation-sys320//week06): Menus and Input Validation +- [week07](https://git.charlotte.sh/lotte/ChamplainTechJournals/src/branch/main/automation-sys320/week07): Scheduled Email Reports +- [week08](https://git.charlotte.sh/lotte/ChamplainTechJournals/src/branch/main/automation-sys320/week08): Midterm +## Bash +- [week09](https://git.charlotte.sh/lotte/ChamplainTechJournals/src/branch/main/automation-sys320/week09): Linux Bash Basics +- [week10](https://git.charlotte.sh/lotte/ChamplainTechJournals/src/branch/main/automation-sys320/week10): Access to File Content +- [week11](https://git.charlotte.sh/lotte/ChamplainTechJournals/src/branch/main/automation-sys320/week11): Flow Control +- week12: No New Assignments +- [week13](https://git.charlotte.sh/lotte/ChamplainTechJournals/src/branch/main/automation-sys320/week13): Web Scraping and Processing +- week14: Thanksgiving Break +- [week15](https://git.charlotte.sh/lotte/ChamplainTechJournals/src/branch/main/automation-sys320/week15): Final diff --git a/automation-sys320/week01/firstfile.ps1 b/automation-sys320/week01/firstfile.ps1 new file mode 100644 index 0000000..b7443eb --- /dev/null +++ b/automation-sys320/week01/firstfile.ps1 @@ -0,0 +1 @@ +powershell first file, for testing Git \ No newline at end of file diff --git a/automation-sys320/week01/github_setup.md b/automation-sys320/week01/github_setup.md new file mode 100644 index 0000000..4487566 --- /dev/null +++ b/automation-sys320/week01/github_setup.md @@ -0,0 +1,41 @@ +# Basic GitHub commands +- Clone repo Using SSH: `git clone git@github.com:charlottecroce/SYS320.git` +- Clone repo Using HTPS: `git clone https://github.com/charlottecroce/SYS320.git` +- Add file to staging area: `git add ` +- Commit change: `git commit -m "commit message"` +- ID needed to commit: `git config --global user.name "charlottecroce"` +- ID needed to commit: `git config --global user.email "charlotte.croce@mymail.champlain.edu"` +- Push changes to repo: `git push` + +- `git remote -v` + - if git is using https and not authenticating. you might have to change it to use ssh + - `git remote set-url origin git@github.com:charlottecroce/champlaintechjournals` + +# Ubuntu Setup +Install Git +- `apt-get update` +- `apt-get install git` + +Create SSH key +- `sudu su` +- `ssh-keygen -t rsa -b 4096 -C "charlotte.croce@mymail.champlain.edu"` +- `ssh-add /root/.ssh/id_rsa` +- Check if SSH agent is running:`eval "$(ssh-agent -s)"` + +Add key to GitHub account +- `cat /root/.ssh/id_rsa.pub` -> copy +- GitHub -> Settings -> SSH and GPG Keys -> New SSH Key -> Select Authentication Key +- Test Connection: `ssh -T git@github.com` + +# Windows Setup +Install Git +- Download Git from https://git-scm.com/download/win +- I select nano as default editory + + +Windows Token Authentication +- When attempting a `git push` you will have an authentication window pop up. We will use token authentication +- Github - Settings - Developer Settings - Tokens(Classic) - Generate a personal access token +- Select the following fields in Scope: repo, write:packages, admin:org, admin:public_key, admin:repo_hook +- Control Panel -> Manage Windows Credentials -> Create Generic Credential -> add GitHub.com:username:password +- Copy the token into the field on the popup and you should be authenticated to push diff --git a/automation-sys320/week02/PowerShellBasicLab.ps1 b/automation-sys320/week02/PowerShellBasicLab.ps1 new file mode 100644 index 0000000..2e3328c --- /dev/null +++ b/automation-sys320/week02/PowerShellBasicLab.ps1 @@ -0,0 +1,62 @@ +# 9/5/24 + +# Part 1 - Networking + +# 1. Get IPv4 address from eth int +(Get-NetIPAddress -AddressFamily IPv4 | ` +Where-Object { $_.InterfaceAlias -ilike "Ethernet0" }).IPAddress + +# 2. Get prefix length from eth int +(Get-NetIPAddress -AddressFamily IPv4 | ` +Where-Object { $_.InterfaceAlias -ilike "Ethernet0" }).PrefixLength + +# 3. Show what classes in Win32 library start with net +Get-WmiObject -List | Where-Object { $_.Name -ilike "Win32_Net*" } + +# 4. ...and sort alphabetically +Get-WmiObject -List | Where-Object { $_.Name -ilike "Win32_Net*" } | Sort-Object + +# 5. Get DHCP server IP +Get-CimInstance Win32_NetworkAdapterConfiguration -Filter "DHCPEnabled=$true" | Select DHCPServer + +# 6. ...and hide table headers +Get-CimInstance Win32_NetworkAdapterConfiguration -Filter "DHCPEnabled=$true" | ` +Select DHCPServer | Format-Table -HideTableHeaders + +# 7. Get DNS server IP for eth int and only display first result +(Get-DnsClientServerAddress -AddressFamily IPv4 | ` +Where-Object { $_.InterfaceAlias -ilike "Ethernet0" }).ServerAddresses[0] + +# Part 2 - Directory Listings + +# 8. List all files in working directory that have extension .ps1 +$files=(Get-ChildItem) +for ($j=0; $j -le $files.Length; $j++){ + if ($files[$j].Name -ilike "*ps1"){ + Write-Host $files[$j].Name + } +} + +# 9. Create a folder called "outfolder" if it does not already exist +$folderpath="$PWD\outfolder" +if (Test-Path $folderpath){ + Write-Host "Folder Already Exists" +} +else{ + New-Item -ItemType "directory" -Path "$folderpath" +} + +# 10. List all files in working directory that have extension .ps1 +# and save results to out.csv file in outfolder directory +$files=(Get-ChildItem) +$folderpath="$PWD\outfolder" +$filepath = Join-Path $folderpath "out.csv" +$files | Where-Object {$_.Extension -eq ".ps1" } | ` +Export-Csv -Path $filepath + +# 11. Without changing directory, find every .csv file and change their extensions to .log, +# then recursively display all the files +$files = Get-ChildItem -File -Recurse +$files | Rename-Item -NewName { $_.Name -replace '.csv', '.log' } +Get-ChildItem -Recurse + diff --git a/automation-sys320/week02/ProcessManagement.ps1 b/automation-sys320/week02/ProcessManagement.ps1 new file mode 100644 index 0000000..c6f2775 --- /dev/null +++ b/automation-sys320/week02/ProcessManagement.ps1 @@ -0,0 +1,25 @@ +#9/5/24 + +# 1. List every process for which ProcessName starts with 'C' +Get-Process | Where-Object { $_.Name -ilike "C*"} + +# 2. List every process for which the path does not include the string "system32" +Get-Process | Where-Object { $_.Name -inotlike "*system32*"} + +# 3. List every stopped service, order alphabetically, and export to csv +Get-Service | Where-Object { $_.Status -eq "Stopped" } | ` +Sort-Object | Export-Csv -Path StoppedServices.csv + +# 4. If Google Chrome browser is not running, start it and direct to champlain.edu +# If it is already running, stop it +if (Get-Process -Name chrome -ErrorAction SilentlyContinue){ + Write-Host "Chrome Running. Stopping now" + Get-Process -name chrome | Stop-Process +} +else{ + Write-Host "Chrome not running. Starting now" + Start-Process 'C:\Program Files\Google\Chrome\Application\chrome.exe' ` + '--new-window https://champlain.edu' +} + + diff --git a/automation-sys320/week02/StoppedServices.log b/automation-sys320/week02/StoppedServices.log new file mode 100644 index 0000000..2c3d1ca --- /dev/null +++ b/automation-sys320/week02/StoppedServices.log @@ -0,0 +1,181 @@ +#TYPE System.ServiceProcess.ServiceController +"Name","RequiredServices","CanPauseAndContinue","CanShutdown","CanStop","DisplayName","DependentServices","MachineName","ServiceName","ServicesDependedOn","ServiceHandle","Status","ServiceType","StartType","Site","Container" +"AJRouter","System.ServiceProcess.ServiceController[]","False","False","False","AllJoyn Router Service","System.ServiceProcess.ServiceController[]",".","AJRouter","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"ALG","System.ServiceProcess.ServiceController[]","False","False","False","Application Layer Gateway Service","System.ServiceProcess.ServiceController[]",".","ALG","System.ServiceProcess.ServiceController[]",,"Stopped","Win32OwnProcess","Manual",, +"AppIDSvc","System.ServiceProcess.ServiceController[]","False","False","False","Application Identity","System.ServiceProcess.ServiceController[]",".","AppIDSvc","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"AppMgmt","System.ServiceProcess.ServiceController[]","False","False","False","Application Management","System.ServiceProcess.ServiceController[]",".","AppMgmt","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"AppReadiness","System.ServiceProcess.ServiceController[]","False","False","False","App Readiness","System.ServiceProcess.ServiceController[]",".","AppReadiness","System.ServiceProcess.ServiceController[]",,"Stopped","Win32OwnProcess, Win32ShareProcess","Manual",, +"AppVClient","System.ServiceProcess.ServiceController[]","False","False","False","Microsoft App-V Client","System.ServiceProcess.ServiceController[]",".","AppVClient","System.ServiceProcess.ServiceController[]",,"Stopped","Win32OwnProcess","Disabled",, +"AppXSvc","System.ServiceProcess.ServiceController[]","False","False","False","AppX Deployment Service (AppXSVC)","System.ServiceProcess.ServiceController[]",".","AppXSvc","System.ServiceProcess.ServiceController[]",,"Stopped","Win32OwnProcess, Win32ShareProcess","Manual",, +"AssignedAccessManagerSvc","System.ServiceProcess.ServiceController[]","False","False","False","AssignedAccessManager Service","System.ServiceProcess.ServiceController[]",".","AssignedAccessManagerSvc","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"AxInstSV","System.ServiceProcess.ServiceController[]","False","False","False","ActiveX Installer (AxInstSV)","System.ServiceProcess.ServiceController[]",".","AxInstSV","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"BcastDVRUserService_70849","System.ServiceProcess.ServiceController[]","False","False","False","GameDVR and Broadcast User Service_70849","System.ServiceProcess.ServiceController[]",".","BcastDVRUserService_70849","System.ServiceProcess.ServiceController[]",,"Stopped","224","Manual",, +"BDESVC","System.ServiceProcess.ServiceController[]","False","False","False","BitLocker Drive Encryption Service","System.ServiceProcess.ServiceController[]",".","BDESVC","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"BITS","System.ServiceProcess.ServiceController[]","False","False","False","Background Intelligent Transfer Service","System.ServiceProcess.ServiceController[]",".","BITS","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"BluetoothUserService_70849","System.ServiceProcess.ServiceController[]","False","False","False","Bluetooth User Support Service_70849","System.ServiceProcess.ServiceController[]",".","BluetoothUserService_70849","System.ServiceProcess.ServiceController[]",,"Stopped","224","Manual",, +"BTAGService","System.ServiceProcess.ServiceController[]","False","False","False","Bluetooth Audio Gateway Service","System.ServiceProcess.ServiceController[]",".","BTAGService","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"BthAvctpSvc","System.ServiceProcess.ServiceController[]","False","False","False","AVCTP service","System.ServiceProcess.ServiceController[]",".","BthAvctpSvc","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"bthserv","System.ServiceProcess.ServiceController[]","False","False","False","Bluetooth Support Service","System.ServiceProcess.ServiceController[]",".","bthserv","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"camsvc","System.ServiceProcess.ServiceController[]","False","False","False","Capability Access Manager Service","System.ServiceProcess.ServiceController[]",".","camsvc","System.ServiceProcess.ServiceController[]",,"Stopped","Win32OwnProcess, Win32ShareProcess","Manual",, +"CaptureService_70849","System.ServiceProcess.ServiceController[]","False","False","False","CaptureService_70849","System.ServiceProcess.ServiceController[]",".","CaptureService_70849","System.ServiceProcess.ServiceController[]",,"Stopped","224","Manual",, +"CertPropSvc","System.ServiceProcess.ServiceController[]","False","False","False","Certificate Propagation","System.ServiceProcess.ServiceController[]",".","CertPropSvc","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"ClipSVC","System.ServiceProcess.ServiceController[]","False","False","False","Client License Service (ClipSVC)","System.ServiceProcess.ServiceController[]",".","ClipSVC","System.ServiceProcess.ServiceController[]",,"Stopped","Win32OwnProcess, Win32ShareProcess","Manual",, +"ConsentUxUserSvc_70849","System.ServiceProcess.ServiceController[]","False","False","False","ConsentUX_70849","System.ServiceProcess.ServiceController[]",".","ConsentUxUserSvc_70849","System.ServiceProcess.ServiceController[]",,"Stopped","224","Manual",, +"CscService","System.ServiceProcess.ServiceController[]","False","False","False","Offline Files","System.ServiceProcess.ServiceController[]",".","CscService","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"defragsvc","System.ServiceProcess.ServiceController[]","False","False","False","Optimize drives","System.ServiceProcess.ServiceController[]",".","defragsvc","System.ServiceProcess.ServiceController[]",,"Stopped","Win32OwnProcess","Manual",, +"DeviceAssociationService","System.ServiceProcess.ServiceController[]","False","False","False","Device Association Service","System.ServiceProcess.ServiceController[]",".","DeviceAssociationService","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"DevicePickerUserSvc_70849","System.ServiceProcess.ServiceController[]","False","False","False","DevicePicker_70849","System.ServiceProcess.ServiceController[]",".","DevicePickerUserSvc_70849","System.ServiceProcess.ServiceController[]",,"Stopped","224","Manual",, +"DevicesFlowUserSvc_70849","System.ServiceProcess.ServiceController[]","False","False","False","DevicesFlow_70849","System.ServiceProcess.ServiceController[]",".","DevicesFlowUserSvc_70849","System.ServiceProcess.ServiceController[]",,"Stopped","224","Manual",, +"DevQueryBroker","System.ServiceProcess.ServiceController[]","False","False","False","DevQuery Background Discovery Broker","System.ServiceProcess.ServiceController[]",".","DevQueryBroker","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"diagnosticshub.standardcollector.service","System.ServiceProcess.ServiceController[]","False","False","False","Microsoft (R) Diagnostics Hub Standard Collector Service","System.ServiceProcess.ServiceController[]",".","diagnosticshub.standardcollector.service","System.ServiceProcess.ServiceController[]",,"Stopped","Win32OwnProcess","Disabled",, +"diagsvc","System.ServiceProcess.ServiceController[]","False","False","False","Diagnostic Execution Service","System.ServiceProcess.ServiceController[]",".","diagsvc","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"DisplayEnhancementService","System.ServiceProcess.ServiceController[]","False","False","False","Display Enhancement Service","System.ServiceProcess.ServiceController[]",".","DisplayEnhancementService","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"DmEnrollmentSvc","System.ServiceProcess.ServiceController[]","False","False","False","Device Management Enrollment Service","System.ServiceProcess.ServiceController[]",".","DmEnrollmentSvc","System.ServiceProcess.ServiceController[]",,"Stopped","Win32OwnProcess","Manual",, +"dmwappushservice","System.ServiceProcess.ServiceController[]","False","False","False","Device Management Wireless Application Protocol (WAP) Push message Routing Service","System.ServiceProcess.ServiceController[]",".","dmwappushservice","System.ServiceProcess.ServiceController[]",,"Stopped","Win32OwnProcess, Win32ShareProcess","Manual",, +"DoSvc","System.ServiceProcess.ServiceController[]","False","False","False","Delivery Optimization","System.ServiceProcess.ServiceController[]",".","DoSvc","System.ServiceProcess.ServiceController[]",,"Stopped","Win32OwnProcess, Win32ShareProcess","Manual",, +"dot3svc","System.ServiceProcess.ServiceController[]","False","False","False","Wired AutoConfig","System.ServiceProcess.ServiceController[]",".","dot3svc","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"DPS","System.ServiceProcess.ServiceController[]","False","False","False","Diagnostic Policy Service","System.ServiceProcess.ServiceController[]",".","DPS","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Disabled",, +"DsmSvc","System.ServiceProcess.ServiceController[]","False","False","False","Device Setup Manager","System.ServiceProcess.ServiceController[]",".","DsmSvc","System.ServiceProcess.ServiceController[]",,"Stopped","Win32OwnProcess, Win32ShareProcess","Manual",, +"DsSvc","System.ServiceProcess.ServiceController[]","False","False","False","Data Sharing Service","System.ServiceProcess.ServiceController[]",".","DsSvc","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"DusmSvc","System.ServiceProcess.ServiceController[]","False","False","False","Data Usage","System.ServiceProcess.ServiceController[]",".","DusmSvc","System.ServiceProcess.ServiceController[]",,"Stopped","Win32OwnProcess","Disabled",, +"Eaphost","System.ServiceProcess.ServiceController[]","False","False","False","Extensible Authentication Protocol","System.ServiceProcess.ServiceController[]",".","Eaphost","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"EFS","System.ServiceProcess.ServiceController[]","False","False","False","Encrypting File System (EFS)","System.ServiceProcess.ServiceController[]",".","EFS","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"embeddedmode","System.ServiceProcess.ServiceController[]","False","False","False","Embedded Mode","System.ServiceProcess.ServiceController[]",".","embeddedmode","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"EntAppSvc","System.ServiceProcess.ServiceController[]","False","False","False","Enterprise App Management Service","System.ServiceProcess.ServiceController[]",".","EntAppSvc","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"Fax","System.ServiceProcess.ServiceController[]","False","False","False","Fax","System.ServiceProcess.ServiceController[]",".","Fax","System.ServiceProcess.ServiceController[]",,"Stopped","Win32OwnProcess","Manual",, +"fdPHost","System.ServiceProcess.ServiceController[]","False","False","False","Function Discovery Provider Host","System.ServiceProcess.ServiceController[]",".","fdPHost","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"FDResPub","System.ServiceProcess.ServiceController[]","False","False","False","Function Discovery Resource Publication","System.ServiceProcess.ServiceController[]",".","FDResPub","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"fhsvc","System.ServiceProcess.ServiceController[]","False","False","False","File History Service","System.ServiceProcess.ServiceController[]",".","fhsvc","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"FrameServer","System.ServiceProcess.ServiceController[]","False","False","False","Windows Camera Frame Server","System.ServiceProcess.ServiceController[]",".","FrameServer","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"GoogleChromeElevationService","System.ServiceProcess.ServiceController[]","False","False","False","Google Chrome Elevation Service (GoogleChromeElevationService)","System.ServiceProcess.ServiceController[]",".","GoogleChromeElevationService","System.ServiceProcess.ServiceController[]",,"Stopped","Win32OwnProcess","Manual",, +"GoogleUpdaterInternalService130.0.6679.0","System.ServiceProcess.ServiceController[]","False","False","False","GoogleUpdater InternalService 130.0.6679.0 (GoogleUpdaterInternalService130.0.6679.0)","System.ServiceProcess.ServiceController[]",".","GoogleUpdaterInternalService130.0.6679.0","System.ServiceProcess.ServiceController[]",,"Stopped","Win32OwnProcess","Automatic",, +"GoogleUpdaterService130.0.6679.0","System.ServiceProcess.ServiceController[]","False","False","False","GoogleUpdater Service 130.0.6679.0 (GoogleUpdaterService130.0.6679.0)","System.ServiceProcess.ServiceController[]",".","GoogleUpdaterService130.0.6679.0","System.ServiceProcess.ServiceController[]",,"Stopped","Win32OwnProcess","Automatic",, +"gpsvc","System.ServiceProcess.ServiceController[]","False","False","False","Group Policy Client","System.ServiceProcess.ServiceController[]",".","gpsvc","System.ServiceProcess.ServiceController[]",,"Stopped","Win32OwnProcess, Win32ShareProcess","Automatic",, +"GraphicsPerfSvc","System.ServiceProcess.ServiceController[]","False","False","False","GraphicsPerfSvc","System.ServiceProcess.ServiceController[]",".","GraphicsPerfSvc","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"hidserv","System.ServiceProcess.ServiceController[]","False","False","False","Human Interface Device Service","System.ServiceProcess.ServiceController[]",".","hidserv","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"HvHost","System.ServiceProcess.ServiceController[]","False","False","False","HV Host Service","System.ServiceProcess.ServiceController[]",".","HvHost","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"icssvc","System.ServiceProcess.ServiceController[]","False","False","False","Windows Mobile Hotspot Service","System.ServiceProcess.ServiceController[]",".","icssvc","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Disabled",, +"IKEEXT","System.ServiceProcess.ServiceController[]","False","False","False","IKE and AuthIP IPsec Keying Modules","System.ServiceProcess.ServiceController[]",".","IKEEXT","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"InstallService","System.ServiceProcess.ServiceController[]","False","False","False","Microsoft Store Install Service","System.ServiceProcess.ServiceController[]",".","InstallService","System.ServiceProcess.ServiceController[]",,"Stopped","Win32OwnProcess","Manual",, +"IpxlatCfgSvc","System.ServiceProcess.ServiceController[]","False","False","False","IP Translation Configuration Service","System.ServiceProcess.ServiceController[]",".","IpxlatCfgSvc","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"irmon","System.ServiceProcess.ServiceController[]","False","False","False","Infrared monitor service","System.ServiceProcess.ServiceController[]",".","irmon","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"KtmRm","System.ServiceProcess.ServiceController[]","False","False","False","KtmRm for Distributed Transaction Coordinator","System.ServiceProcess.ServiceController[]",".","KtmRm","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"lfsvc","System.ServiceProcess.ServiceController[]","False","False","False","Geolocation Service","System.ServiceProcess.ServiceController[]",".","lfsvc","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"lltdsvc","System.ServiceProcess.ServiceController[]","False","False","False","Link-Layer Topology Discovery Mapper","System.ServiceProcess.ServiceController[]",".","lltdsvc","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"LxpSvc","System.ServiceProcess.ServiceController[]","False","False","False","Language Experience Service","System.ServiceProcess.ServiceController[]",".","LxpSvc","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"MapsBroker","System.ServiceProcess.ServiceController[]","False","False","False","Downloaded Maps Manager","System.ServiceProcess.ServiceController[]",".","MapsBroker","System.ServiceProcess.ServiceController[]",,"Stopped","Win32OwnProcess","Automatic",, +"MessagingService_70849","System.ServiceProcess.ServiceController[]","False","False","False","MessagingService_70849","System.ServiceProcess.ServiceController[]",".","MessagingService_70849","System.ServiceProcess.ServiceController[]",,"Stopped","224","Manual",, +"MSiSCSI","System.ServiceProcess.ServiceController[]","False","False","False","Microsoft iSCSI Initiator Service","System.ServiceProcess.ServiceController[]",".","MSiSCSI","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"msiserver","System.ServiceProcess.ServiceController[]","False","False","False","Windows Installer","System.ServiceProcess.ServiceController[]",".","msiserver","System.ServiceProcess.ServiceController[]",,"Stopped","Win32OwnProcess","Manual",, +"NaturalAuthentication","System.ServiceProcess.ServiceController[]","False","False","False","Natural Authentication","System.ServiceProcess.ServiceController[]",".","NaturalAuthentication","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"NcaSvc","System.ServiceProcess.ServiceController[]","False","False","False","Network Connectivity Assistant","System.ServiceProcess.ServiceController[]",".","NcaSvc","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"NcdAutoSetup","System.ServiceProcess.ServiceController[]","False","False","False","Network Connected Devices Auto-Setup","System.ServiceProcess.ServiceController[]",".","NcdAutoSetup","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"Netlogon","System.ServiceProcess.ServiceController[]","False","False","False","Netlogon","System.ServiceProcess.ServiceController[]",".","Netlogon","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"Netman","System.ServiceProcess.ServiceController[]","False","False","False","Network Connections","System.ServiceProcess.ServiceController[]",".","Netman","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"NetSetupSvc","System.ServiceProcess.ServiceController[]","False","False","False","Network Setup Service","System.ServiceProcess.ServiceController[]",".","NetSetupSvc","System.ServiceProcess.ServiceController[]",,"Stopped","Win32OwnProcess, Win32ShareProcess","Manual",, +"NetTcpPortSharing","System.ServiceProcess.ServiceController[]","False","False","False","Net.Tcp Port Sharing Service","System.ServiceProcess.ServiceController[]",".","NetTcpPortSharing","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Disabled",, +"NgcCtnrSvc","System.ServiceProcess.ServiceController[]","False","False","False","Microsoft Passport Container",,".","NgcCtnrSvc","System.ServiceProcess.ServiceController[]",,"Stopped","Win32OwnProcess, Win32ShareProcess","Manual",, +"NgcSvc","System.ServiceProcess.ServiceController[]","False","False","False","Microsoft Passport",,".","NgcSvc","System.ServiceProcess.ServiceController[]",,"Stopped","Win32OwnProcess, Win32ShareProcess","Manual",, +"p2pimsvc","System.ServiceProcess.ServiceController[]","False","False","False","Peer Networking Identity Manager","System.ServiceProcess.ServiceController[]",".","p2pimsvc","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"p2psvc","System.ServiceProcess.ServiceController[]","False","False","False","Peer Networking Grouping","System.ServiceProcess.ServiceController[]",".","p2psvc","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"PeerDistSvc","System.ServiceProcess.ServiceController[]","False","False","False","BranchCache","System.ServiceProcess.ServiceController[]",".","PeerDistSvc","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"perceptionsimulation","System.ServiceProcess.ServiceController[]","False","False","False","Windows Perception Simulation Service","System.ServiceProcess.ServiceController[]",".","perceptionsimulation","System.ServiceProcess.ServiceController[]",,"Stopped","Win32OwnProcess","Manual",, +"PerfHost","System.ServiceProcess.ServiceController[]","False","False","False","Performance Counter DLL Host","System.ServiceProcess.ServiceController[]",".","PerfHost","System.ServiceProcess.ServiceController[]",,"Stopped","Win32OwnProcess","Manual",, +"PhoneSvc","System.ServiceProcess.ServiceController[]","False","False","False","Phone Service","System.ServiceProcess.ServiceController[]",".","PhoneSvc","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"PimIndexMaintenanceSvc_70849","System.ServiceProcess.ServiceController[]","False","False","False","Contact Data_70849","System.ServiceProcess.ServiceController[]",".","PimIndexMaintenanceSvc_70849","System.ServiceProcess.ServiceController[]",,"Stopped","224","Manual",, +"pla","System.ServiceProcess.ServiceController[]","False","False","False","Performance Logs & Alerts",,".","pla","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"PNRPAutoReg","System.ServiceProcess.ServiceController[]","False","False","False","PNRP Machine Name Publication Service","System.ServiceProcess.ServiceController[]",".","PNRPAutoReg","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"PNRPsvc","System.ServiceProcess.ServiceController[]","False","False","False","Peer Name Resolution Protocol","System.ServiceProcess.ServiceController[]",".","PNRPsvc","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"PolicyAgent","System.ServiceProcess.ServiceController[]","False","False","False","IPsec Policy Agent","System.ServiceProcess.ServiceController[]",".","PolicyAgent","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"PrintNotify","System.ServiceProcess.ServiceController[]","False","False","False","Printer Extensions and Notifications","System.ServiceProcess.ServiceController[]",".","PrintNotify","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess, InteractiveProcess","Manual",, +"PrintWorkflowUserSvc_70849","System.ServiceProcess.ServiceController[]","False","False","False","PrintWorkflow_70849","System.ServiceProcess.ServiceController[]",".","PrintWorkflowUserSvc_70849","System.ServiceProcess.ServiceController[]",,"Stopped","224","Manual",, +"PushToInstall","System.ServiceProcess.ServiceController[]","False","False","False","Windows PushToInstall Service","System.ServiceProcess.ServiceController[]",".","PushToInstall","System.ServiceProcess.ServiceController[]",,"Stopped","Win32OwnProcess, Win32ShareProcess","Manual",, +"QWAVE","System.ServiceProcess.ServiceController[]","False","False","False","Quality Windows Audio Video Experience","System.ServiceProcess.ServiceController[]",".","QWAVE","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"RasAuto","System.ServiceProcess.ServiceController[]","False","False","False","Remote Access Auto Connection Manager","System.ServiceProcess.ServiceController[]",".","RasAuto","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"RasMan","System.ServiceProcess.ServiceController[]","False","False","False","Remote Access Connection Manager","System.ServiceProcess.ServiceController[]",".","RasMan","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"RemoteAccess","System.ServiceProcess.ServiceController[]","False","False","False","Routing and Remote Access","System.ServiceProcess.ServiceController[]",".","RemoteAccess","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Disabled",, +"RemoteRegistry","System.ServiceProcess.ServiceController[]","False","False","False","Remote Registry","System.ServiceProcess.ServiceController[]",".","RemoteRegistry","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Disabled",, +"RetailDemo","System.ServiceProcess.ServiceController[]","False","False","False","Retail Demo Service","System.ServiceProcess.ServiceController[]",".","RetailDemo","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Disabled",, +"RmSvc","System.ServiceProcess.ServiceController[]","False","False","False","Radio Management Service","System.ServiceProcess.ServiceController[]",".","RmSvc","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Disabled",, +"RpcLocator","System.ServiceProcess.ServiceController[]","False","False","False","Remote Procedure Call (RPC) Locator","System.ServiceProcess.ServiceController[]",".","RpcLocator","System.ServiceProcess.ServiceController[]",,"Stopped","Win32OwnProcess","Manual",, +"SCardSvr","System.ServiceProcess.ServiceController[]","False","False","False","Smart Card","System.ServiceProcess.ServiceController[]",".","SCardSvr","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"ScDeviceEnum","System.ServiceProcess.ServiceController[]","False","False","False","Smart Card Device Enumeration Service","System.ServiceProcess.ServiceController[]",".","ScDeviceEnum","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"SCPolicySvc","System.ServiceProcess.ServiceController[]","False","False","False","Smart Card Removal Policy","System.ServiceProcess.ServiceController[]",".","SCPolicySvc","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"SDRSVC","System.ServiceProcess.ServiceController[]","False","False","False","Windows Backup","System.ServiceProcess.ServiceController[]",".","SDRSVC","System.ServiceProcess.ServiceController[]",,"Stopped","Win32OwnProcess","Manual",, +"seclogon","System.ServiceProcess.ServiceController[]","False","False","False","Secondary Logon","System.ServiceProcess.ServiceController[]",".","seclogon","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"SEMgrSvc","System.ServiceProcess.ServiceController[]","False","False","False","Payments and NFC/SE Manager","System.ServiceProcess.ServiceController[]",".","SEMgrSvc","System.ServiceProcess.ServiceController[]",,"Stopped","Win32OwnProcess","Disabled",, +"Sense","System.ServiceProcess.ServiceController[]","False","False","False","Windows Defender Advanced Threat Protection Service","System.ServiceProcess.ServiceController[]",".","Sense","System.ServiceProcess.ServiceController[]",,"Stopped","Win32OwnProcess","Manual",, +"SensorDataService","System.ServiceProcess.ServiceController[]","False","False","False","Sensor Data Service","System.ServiceProcess.ServiceController[]",".","SensorDataService","System.ServiceProcess.ServiceController[]",,"Stopped","Win32OwnProcess","Manual",, +"SensorService","System.ServiceProcess.ServiceController[]","False","False","False","Sensor Service","System.ServiceProcess.ServiceController[]",".","SensorService","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"SensrSvc","System.ServiceProcess.ServiceController[]","False","False","False","Sensor Monitoring Service","System.ServiceProcess.ServiceController[]",".","SensrSvc","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"SessionEnv","System.ServiceProcess.ServiceController[]","False","False","False","Remote Desktop Configuration","System.ServiceProcess.ServiceController[]",".","SessionEnv","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"SharedAccess","System.ServiceProcess.ServiceController[]","False","False","False","Internet Connection Sharing (ICS)","System.ServiceProcess.ServiceController[]",".","SharedAccess","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"SharedRealitySvc","System.ServiceProcess.ServiceController[]","False","False","False","Spatial Data Service","System.ServiceProcess.ServiceController[]",".","SharedRealitySvc","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"shpamsvc","System.ServiceProcess.ServiceController[]","False","False","False","Shared PC Account Manager","System.ServiceProcess.ServiceController[]",".","shpamsvc","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Disabled",, +"smphost","System.ServiceProcess.ServiceController[]","False","False","False","Microsoft Storage Spaces SMP","System.ServiceProcess.ServiceController[]",".","smphost","System.ServiceProcess.ServiceController[]",,"Stopped","Win32OwnProcess","Manual",, +"SmsRouter","System.ServiceProcess.ServiceController[]","False","False","False","Microsoft Windows SMS Router Service.",,".","SmsRouter","System.ServiceProcess.ServiceController[]",,"Stopped","Win32OwnProcess, Win32ShareProcess","Manual",, +"SNMPTRAP","System.ServiceProcess.ServiceController[]","False","False","False","SNMP Trap","System.ServiceProcess.ServiceController[]",".","SNMPTRAP","System.ServiceProcess.ServiceController[]",,"Stopped","Win32OwnProcess","Manual",, +"spectrum","System.ServiceProcess.ServiceController[]","False","False","False","Windows Perception Service","System.ServiceProcess.ServiceController[]",".","spectrum","System.ServiceProcess.ServiceController[]",,"Stopped","Win32OwnProcess","Manual",, +"sppsvc","System.ServiceProcess.ServiceController[]","False","False","False","Software Protection","System.ServiceProcess.ServiceController[]",".","sppsvc","System.ServiceProcess.ServiceController[]",,"Stopped","Win32OwnProcess","Automatic",, +"ssh-agent","System.ServiceProcess.ServiceController[]","False","False","False","OpenSSH Authentication Agent","System.ServiceProcess.ServiceController[]",".","ssh-agent","System.ServiceProcess.ServiceController[]",,"Stopped","Win32OwnProcess","Disabled",, +"SstpSvc","System.ServiceProcess.ServiceController[]","False","False","False","Secure Socket Tunneling Protocol Service","System.ServiceProcess.ServiceController[]",".","SstpSvc","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"stisvc","System.ServiceProcess.ServiceController[]","False","False","False","Windows Image Acquisition (WIA)","System.ServiceProcess.ServiceController[]",".","stisvc","System.ServiceProcess.ServiceController[]",,"Stopped","Win32OwnProcess","Manual",, +"svsvc","System.ServiceProcess.ServiceController[]","False","False","False","Spot Verifier","System.ServiceProcess.ServiceController[]",".","svsvc","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"swprv","System.ServiceProcess.ServiceController[]","False","False","False","Microsoft Software Shadow Copy Provider","System.ServiceProcess.ServiceController[]",".","swprv","System.ServiceProcess.ServiceController[]",,"Stopped","Win32OwnProcess","Manual",, +"TapiSrv","System.ServiceProcess.ServiceController[]","False","False","False","Telephony","System.ServiceProcess.ServiceController[]",".","TapiSrv","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"TermService","System.ServiceProcess.ServiceController[]","False","False","False","Remote Desktop Services","System.ServiceProcess.ServiceController[]",".","TermService","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"TieringEngineService","System.ServiceProcess.ServiceController[]","False","False","False","Storage Tiers Management","System.ServiceProcess.ServiceController[]",".","TieringEngineService","System.ServiceProcess.ServiceController[]",,"Stopped","Win32OwnProcess","Manual",, +"TrkWks","System.ServiceProcess.ServiceController[]","False","False","False","Distributed Link Tracking Client","System.ServiceProcess.ServiceController[]",".","TrkWks","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Disabled",, +"TrustedInstaller","System.ServiceProcess.ServiceController[]","False","False","False","Windows Modules Installer","System.ServiceProcess.ServiceController[]",".","TrustedInstaller","System.ServiceProcess.ServiceController[]",,"Stopped","Win32OwnProcess","Manual",, +"tzautoupdate","System.ServiceProcess.ServiceController[]","False","False","False","Auto Time Zone Updater","System.ServiceProcess.ServiceController[]",".","tzautoupdate","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Disabled",, +"UevAgentService","System.ServiceProcess.ServiceController[]","False","False","False","User Experience Virtualization Service","System.ServiceProcess.ServiceController[]",".","UevAgentService","System.ServiceProcess.ServiceController[]",,"Stopped","Win32OwnProcess","Disabled",, +"UmRdpService","System.ServiceProcess.ServiceController[]","False","False","False","Remote Desktop Services UserMode Port Redirector","System.ServiceProcess.ServiceController[]",".","UmRdpService","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"UnistoreSvc_70849","System.ServiceProcess.ServiceController[]","False","False","False","User Data Storage_70849","System.ServiceProcess.ServiceController[]",".","UnistoreSvc_70849","System.ServiceProcess.ServiceController[]",,"Stopped","224","Manual",, +"upnphost","System.ServiceProcess.ServiceController[]","False","False","False","UPnP Device Host","System.ServiceProcess.ServiceController[]",".","upnphost","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"UserDataSvc_70849","System.ServiceProcess.ServiceController[]","False","False","False","User Data Access_70849","System.ServiceProcess.ServiceController[]",".","UserDataSvc_70849","System.ServiceProcess.ServiceController[]",,"Stopped","224","Manual",, +"VacSvc","System.ServiceProcess.ServiceController[]","False","False","False","Volumetric Audio Compositor Service","System.ServiceProcess.ServiceController[]",".","VacSvc","System.ServiceProcess.ServiceController[]",,"Stopped","Win32OwnProcess","Manual",, +"vds","System.ServiceProcess.ServiceController[]","False","False","False","Virtual Disk","System.ServiceProcess.ServiceController[]",".","vds","System.ServiceProcess.ServiceController[]",,"Stopped","Win32OwnProcess","Manual",, +"vmicguestinterface","System.ServiceProcess.ServiceController[]","False","False","False","Hyper-V Guest Service Interface","System.ServiceProcess.ServiceController[]",".","vmicguestinterface","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"vmicheartbeat","System.ServiceProcess.ServiceController[]","False","False","False","Hyper-V Heartbeat Service","System.ServiceProcess.ServiceController[]",".","vmicheartbeat","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"vmickvpexchange","System.ServiceProcess.ServiceController[]","False","False","False","Hyper-V Data Exchange Service","System.ServiceProcess.ServiceController[]",".","vmickvpexchange","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"vmicrdv","System.ServiceProcess.ServiceController[]","False","False","False","Hyper-V Remote Desktop Virtualization Service","System.ServiceProcess.ServiceController[]",".","vmicrdv","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"vmicshutdown","System.ServiceProcess.ServiceController[]","False","False","False","Hyper-V Guest Shutdown Service","System.ServiceProcess.ServiceController[]",".","vmicshutdown","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"vmictimesync","System.ServiceProcess.ServiceController[]","False","False","False","Hyper-V Time Synchronization Service","System.ServiceProcess.ServiceController[]",".","vmictimesync","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"vmicvmsession","System.ServiceProcess.ServiceController[]","False","False","False","Hyper-V PowerShell Direct Service","System.ServiceProcess.ServiceController[]",".","vmicvmsession","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"vmicvss","System.ServiceProcess.ServiceController[]","False","False","False","Hyper-V Volume Shadow Copy Requestor","System.ServiceProcess.ServiceController[]",".","vmicvss","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"vmvss","System.ServiceProcess.ServiceController[]","False","False","False","VMware Snapshot Provider","System.ServiceProcess.ServiceController[]",".","vmvss","System.ServiceProcess.ServiceController[]",,"Stopped","Win32OwnProcess","Manual",, +"VSS","System.ServiceProcess.ServiceController[]","False","False","False","Volume Shadow Copy","System.ServiceProcess.ServiceController[]",".","VSS","System.ServiceProcess.ServiceController[]",,"Stopped","Win32OwnProcess","Manual",, +"W32Time","System.ServiceProcess.ServiceController[]","False","False","False","Windows Time","System.ServiceProcess.ServiceController[]",".","W32Time","System.ServiceProcess.ServiceController[]",,"Stopped","Win32OwnProcess, Win32ShareProcess","Manual",, +"WaaSMedicSvc","System.ServiceProcess.ServiceController[]","False","False","False","Windows Update Medic Service","System.ServiceProcess.ServiceController[]",".","WaaSMedicSvc","System.ServiceProcess.ServiceController[]",,"Stopped","Win32OwnProcess, Win32ShareProcess","Manual",, +"WalletService","System.ServiceProcess.ServiceController[]","False","False","False","WalletService","System.ServiceProcess.ServiceController[]",".","WalletService","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"WarpJITSvc","System.ServiceProcess.ServiceController[]","False","False","False","WarpJITSvc","System.ServiceProcess.ServiceController[]",".","WarpJITSvc","System.ServiceProcess.ServiceController[]",,"Stopped","Win32OwnProcess","Manual",, +"wbengine","System.ServiceProcess.ServiceController[]","False","False","False","Block Level Backup Engine Service","System.ServiceProcess.ServiceController[]",".","wbengine","System.ServiceProcess.ServiceController[]",,"Stopped","Win32OwnProcess","Manual",, +"WbioSrvc","System.ServiceProcess.ServiceController[]","False","False","False","Windows Biometric Service","System.ServiceProcess.ServiceController[]",".","WbioSrvc","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"wcncsvc","System.ServiceProcess.ServiceController[]","False","False","False","Windows Connect Now - Config Registrar","System.ServiceProcess.ServiceController[]",".","wcncsvc","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"WdiServiceHost","System.ServiceProcess.ServiceController[]","False","False","False","Diagnostic Service Host","System.ServiceProcess.ServiceController[]",".","WdiServiceHost","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"WdiSystemHost","System.ServiceProcess.ServiceController[]","False","False","False","Diagnostic System Host","System.ServiceProcess.ServiceController[]",".","WdiSystemHost","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"WebClient","System.ServiceProcess.ServiceController[]","False","False","False","WebClient","System.ServiceProcess.ServiceController[]",".","WebClient","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"Wecsvc","System.ServiceProcess.ServiceController[]","False","False","False","Windows Event Collector","System.ServiceProcess.ServiceController[]",".","Wecsvc","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"WEPHOSTSVC","System.ServiceProcess.ServiceController[]","False","False","False","Windows Encryption Provider Host Service","System.ServiceProcess.ServiceController[]",".","WEPHOSTSVC","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"wercplsupport","System.ServiceProcess.ServiceController[]","False","False","False","Problem Reports and Solutions Control Panel Support","System.ServiceProcess.ServiceController[]",".","wercplsupport","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"WerSvc","System.ServiceProcess.ServiceController[]","False","False","False","Windows Error Reporting Service","System.ServiceProcess.ServiceController[]",".","WerSvc","System.ServiceProcess.ServiceController[]",,"Stopped","Win32OwnProcess","Disabled",, +"WFDSConMgrSvc","System.ServiceProcess.ServiceController[]","False","False","False","Wi-Fi Direct Services Connection Manager Service","System.ServiceProcess.ServiceController[]",".","WFDSConMgrSvc","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"WiaRpc","System.ServiceProcess.ServiceController[]","False","False","False","Still Image Acquisition Events","System.ServiceProcess.ServiceController[]",".","WiaRpc","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"WinRM","System.ServiceProcess.ServiceController[]","False","False","False","Windows Remote Management (WS-Management)","System.ServiceProcess.ServiceController[]",".","WinRM","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"wisvc","System.ServiceProcess.ServiceController[]","False","False","False","Windows Insider Service","System.ServiceProcess.ServiceController[]",".","wisvc","System.ServiceProcess.ServiceController[]",,"Stopped","Win32OwnProcess, Win32ShareProcess","Manual",, +"WlanSvc","System.ServiceProcess.ServiceController[]","False","False","False","WLAN AutoConfig","System.ServiceProcess.ServiceController[]",".","WlanSvc","System.ServiceProcess.ServiceController[]",,"Stopped","Win32OwnProcess","Manual",, +"wlidsvc","System.ServiceProcess.ServiceController[]","False","False","False","Microsoft Account Sign-in Assistant","System.ServiceProcess.ServiceController[]",".","wlidsvc","System.ServiceProcess.ServiceController[]",,"Stopped","Win32OwnProcess, Win32ShareProcess","Manual",, +"wlpasvc","System.ServiceProcess.ServiceController[]","False","False","False","Local Profile Assistant Service","System.ServiceProcess.ServiceController[]",".","wlpasvc","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"WManSvc","System.ServiceProcess.ServiceController[]","False","False","False","Windows Management Service","System.ServiceProcess.ServiceController[]",".","WManSvc","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"wmiApSrv","System.ServiceProcess.ServiceController[]","False","False","False","WMI Performance Adapter","System.ServiceProcess.ServiceController[]",".","wmiApSrv","System.ServiceProcess.ServiceController[]",,"Stopped","Win32OwnProcess","Manual",, +"WMPNetworkSvc","System.ServiceProcess.ServiceController[]","False","False","False","Windows Media Player Network Sharing Service","System.ServiceProcess.ServiceController[]",".","WMPNetworkSvc","System.ServiceProcess.ServiceController[]",,"Stopped","Win32OwnProcess","Manual",, +"workfolderssvc","System.ServiceProcess.ServiceController[]","False","False","False","Work Folders","System.ServiceProcess.ServiceController[]",".","workfolderssvc","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"WpcMonSvc","System.ServiceProcess.ServiceController[]","False","False","False","Parental Controls","System.ServiceProcess.ServiceController[]",".","WpcMonSvc","System.ServiceProcess.ServiceController[]",,"Stopped","Win32OwnProcess","Manual",, +"WPDBusEnum","System.ServiceProcess.ServiceController[]","False","False","False","Portable Device Enumerator Service","System.ServiceProcess.ServiceController[]",".","WPDBusEnum","System.ServiceProcess.ServiceController[]",,"Stopped","Win32OwnProcess, Win32ShareProcess","Manual",, +"WSearch","System.ServiceProcess.ServiceController[]","False","False","False","Windows Search","System.ServiceProcess.ServiceController[]",".","WSearch","System.ServiceProcess.ServiceController[]",,"Stopped","Win32OwnProcess","Disabled",, +"wuauserv","System.ServiceProcess.ServiceController[]","False","False","False","Windows Update","System.ServiceProcess.ServiceController[]",".","wuauserv","System.ServiceProcess.ServiceController[]",,"Stopped","Win32OwnProcess, Win32ShareProcess","Manual",, +"WwanSvc","System.ServiceProcess.ServiceController[]","False","False","False","WWAN AutoConfig","System.ServiceProcess.ServiceController[]",".","WwanSvc","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"XblAuthManager","System.ServiceProcess.ServiceController[]","False","False","False","Xbox Live Auth Manager","System.ServiceProcess.ServiceController[]",".","XblAuthManager","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"XblGameSave","System.ServiceProcess.ServiceController[]","False","False","False","Xbox Live Game Save","System.ServiceProcess.ServiceController[]",".","XblGameSave","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"XboxGipSvc","System.ServiceProcess.ServiceController[]","False","False","False","Xbox Accessory Management Service","System.ServiceProcess.ServiceController[]",".","XboxGipSvc","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, +"XboxNetApiSvc","System.ServiceProcess.ServiceController[]","False","False","False","Xbox Live Networking Service","System.ServiceProcess.ServiceController[]",".","XboxNetApiSvc","System.ServiceProcess.ServiceController[]",,"Stopped","Win32ShareProcess","Manual",, diff --git a/automation-sys320/week02/outfolder/out.log b/automation-sys320/week02/outfolder/out.log new file mode 100644 index 0000000..1d20888 --- /dev/null +++ b/automation-sys320/week02/outfolder/out.log @@ -0,0 +1,58 @@ +#TYPE System.IO.FileInfo +"PSPath","PSParentPath","PSChildName","PSDrive","PSProvider","PSIsContainer","Mode","VersionInfo","BaseName","Target","LinkType","Name","Length","DirectoryName","Directory","IsReadOnly","Exists","FullName","Extension","CreationTime","CreationTimeUtc","LastAccessTime","LastAccessTimeUtc","LastWriteTime","LastWriteTimeUtc","Attributes" +"Microsoft.PowerShell.Core\FileSystem::C:\Users\champuser\SYS320\week2\empty1.ps1","Microsoft.PowerShell.Core\FileSystem::C:\Users\champuser\SYS320\week2","empty1.ps1","C","Microsoft.PowerShell.Core\FileSystem","False","-a----","File: C:\Users\champuser\SYS320\week2\empty1.ps1 +InternalName: +OriginalFilename: +FileVersion: +FileDescription: +Product: +ProductVersion: +Debug: False +Patched: False +PreRelease: False +PrivateBuild: False +SpecialBuild: False +Language: +","empty1","System.Collections.Generic.List`1[System.String]",,"empty1.ps1","0","C:\Users\champuser\SYS320\week2","C:\Users\champuser\SYS320\week2","False","True","C:\Users\champuser\SYS320\week2\empty1.ps1",".ps1","9/5/2024 2:29:22 PM","9/5/2024 6:29:22 PM","9/5/2024 2:29:22 PM","9/5/2024 6:29:22 PM","9/5/2024 2:29:22 PM","9/5/2024 6:29:22 PM","Archive" +"Microsoft.PowerShell.Core\FileSystem::C:\Users\champuser\SYS320\week2\empty2.ps1","Microsoft.PowerShell.Core\FileSystem::C:\Users\champuser\SYS320\week2","empty2.ps1","C","Microsoft.PowerShell.Core\FileSystem","False","-a----","File: C:\Users\champuser\SYS320\week2\empty2.ps1 +InternalName: +OriginalFilename: +FileVersion: +FileDescription: +Product: +ProductVersion: +Debug: False +Patched: False +PreRelease: False +PrivateBuild: False +SpecialBuild: False +Language: +","empty2","System.Collections.Generic.List`1[System.String]",,"empty2.ps1","0","C:\Users\champuser\SYS320\week2","C:\Users\champuser\SYS320\week2","False","True","C:\Users\champuser\SYS320\week2\empty2.ps1",".ps1","9/5/2024 2:29:29 PM","9/5/2024 6:29:29 PM","9/5/2024 2:29:29 PM","9/5/2024 6:29:29 PM","9/5/2024 2:29:29 PM","9/5/2024 6:29:29 PM","Archive" +"Microsoft.PowerShell.Core\FileSystem::C:\Users\champuser\SYS320\week2\empty4.ps1","Microsoft.PowerShell.Core\FileSystem::C:\Users\champuser\SYS320\week2","empty4.ps1","C","Microsoft.PowerShell.Core\FileSystem","False","-a----","File: C:\Users\champuser\SYS320\week2\empty4.ps1 +InternalName: +OriginalFilename: +FileVersion: +FileDescription: +Product: +ProductVersion: +Debug: False +Patched: False +PreRelease: False +PrivateBuild: False +SpecialBuild: False +Language: +","empty4","System.Collections.Generic.List`1[System.String]",,"empty4.ps1","0","C:\Users\champuser\SYS320\week2","C:\Users\champuser\SYS320\week2","False","True","C:\Users\champuser\SYS320\week2\empty4.ps1",".ps1","9/5/2024 2:29:34 PM","9/5/2024 6:29:34 PM","9/5/2024 2:29:34 PM","9/5/2024 6:29:34 PM","9/5/2024 2:29:34 PM","9/5/2024 6:29:34 PM","Archive" +"Microsoft.PowerShell.Core\FileSystem::C:\Users\champuser\SYS320\week2\PowerShellBasicLab.ps1","Microsoft.PowerShell.Core\FileSystem::C:\Users\champuser\SYS320\week2","PowerShellBasicLab.ps1","C","Microsoft.PowerShell.Core\FileSystem","False","-a----","File: C:\Users\champuser\SYS320\week2\PowerShellBasicLab.ps1 +InternalName: +OriginalFilename: +FileVersion: +FileDescription: +Product: +ProductVersion: +Debug: False +Patched: False +PreRelease: False +PrivateBuild: False +SpecialBuild: False +Language: +","PowerShellBasicLab","System.Collections.Generic.List`1[System.String]",,"PowerShellBasicLab.ps1","1625","C:\Users\champuser\SYS320\week2","C:\Users\champuser\SYS320\week2","False","True","C:\Users\champuser\SYS320\week2\PowerShellBasicLab.ps1",".ps1","9/5/2024 2:07:40 PM","9/5/2024 6:07:40 PM","9/5/2024 2:13:46 PM","9/5/2024 6:13:46 PM","9/5/2024 2:13:46 PM","9/5/2024 6:13:46 PM","Archive" diff --git a/automation-sys320/week03/ExternalScript.ps1 b/automation-sys320/week03/ExternalScript.ps1 new file mode 100644 index 0000000..4923070 --- /dev/null +++ b/automation-sys320/week03/ExternalScript.ps1 @@ -0,0 +1,9 @@ +(Join-Path $PSScriptRoot .\FunctionsAndEventLogs.ps1) + +# get login and logoffs from past 14 days +$loginoutsTable = getWinLogons(14) +$loginoutsTable + +# get shutdowns from past 20 days +$shutdownsTable = getShutdowns(20) +$shutdownsTable diff --git a/automation-sys320/week03/FunctionsAndEventLogs.ps1 b/automation-sys320/week03/FunctionsAndEventLogs.ps1 new file mode 100644 index 0000000..66ad88b --- /dev/null +++ b/automation-sys320/week03/FunctionsAndEventLogs.ps1 @@ -0,0 +1,64 @@ +# 9/12/24 + +# 1. Get login and logoff records from Windows Events +#Get-EventLog System -source Microsoft-Windows-Winlogon + +# 2. Get login and logoff reords from windows events and save to a variable +# Get the last 14 days +# 3. Translate SID to Username +# 4. Turn to function with 1 input (number of days) +function getWinLogons ($days){ + $loginouts = Get-EventLog System -source Microsoft-Windows-Winlogon -After (Get-Date).AddDays(-$days) + + $loginoutsTable = @() + for($i=0; $i -lt $loginouts.Count; $i++){ + + # create event property value + $event = "" + if($loginouts[$i].InstanceID -eq 7001) {$event="Logon"} + if($loginouts[$i].InstanceID -eq 7002) {$event="Logoff"} + + # create user property value + $userSID = New-Object System.Security.Principal.SecurityIdentifier ` + ($loginouts[$i].ReplacementStrings[1]) + $userNAME = $userSID.Translate([System.Security.Principal.NTAccount]) + + # add each entry to table + $loginoutsTable += [pscustomobject]@{"Time" = $loginouts[$i].TimeGenerated; ` + "Id" = $loginouts[$i].InstanceId; ` + "Event" = $event; ` + "User" = $userNAME; + } + } + return $loginoutsTable +} + +#getWinLogons(30) + + +# 5. Get shutdown and start events +function getShutdowns ($days){ + + $shutdowns = Get-EventLog System -After (Get-Date).AddDays(-$days) | where { $_.EventID -match "600[56]" } + + $shutdownsTable = @() + for($i=0; $i -lt $shutdowns.Count; $i++){ + + + # create event property value + $event = "" + if($shutdowns[$i].EventID -eq 6006) {$event="Shutdown"} + if($shutdowns[$i].EventID -eq 6005) {$event="Start"} + + # add each entry to table + $shutdownsTable += [pscustomobject]@{"Time" = $shutdowns[$i].TimeGenerated; ` + "Id" = $shutdowns[$i].EventId; ` + "Event" = $event; ` + "User" = "SYSTEM"; + } + } + return $shutdownsTable +} + +#getShutdowns + diff --git a/automation-sys320/week04/Apache-Logs.ps1 b/automation-sys320/week04/Apache-Logs.ps1 new file mode 100644 index 0000000..975af9f --- /dev/null +++ b/automation-sys320/week04/Apache-Logs.ps1 @@ -0,0 +1,34 @@ +# 9/26/24 + +# input page name, http code, and browser +# output IP addresses that visited the given page, with given browser, and got given HTTP response +Function Apache-Logs ([string]$page, [string]$HTTPcode, [string]$browser){ + $logsnotformatted = Get-Content C:\xampp\apache\logs\access.log + $tablerecords = @() + + for($i=0; $i -lt $logsnotformatted.Length; $i++){ + + # split string into words + $words = $logsnotformatted[$i] -split " " + + # filter out logs that don't match inputs + if(($words[6] -inotlike $page) -OR ($words[8] -inotcontains $HTTPcode) ` + -OR ($words[11].Trim('"') -inotlike $browser)){ + continue + } + + # create custom objects for matches + $tablerecords += [pscustomobject]@{"IP" = $words[0]; ` + "Page" = $words[6]; ` + "Response" = $words[8]; ` + "Browser" = -join $words[11..($words.Length - 1)]; } + }# end of for loop + + return $tablerecords + +} +#$ips1 = Apache-Logs "/index.html" "200" "Mozilla/5.0" +#$ips1 + +#$ips2 = Apache-Logs "/*external*" "404" "Mozilla/5.0" +#$ips2 \ No newline at end of file diff --git a/automation-sys320/week04/ParsingApacheLogs.ps1 b/automation-sys320/week04/ParsingApacheLogs.ps1 new file mode 100644 index 0000000..4397414 --- /dev/null +++ b/automation-sys320/week04/ParsingApacheLogs.ps1 @@ -0,0 +1,26 @@ +# 9/26/24 + +# parses apache log into pscustomobjects, filters IPs for 10.* +function ApacheLogs1(){ +$logsnotformatted = Get-Content C:\xampp\apache\logs\access.log +$tablerecords = @() + + for($i=0; $i -lt $logsnotformatted.Length; $i++){ + + # split string into words + $words = $logsnotformatted[$i] -split " " + + $tablerecords += [pscustomobject]@{"IP" = $words[0]; ` + "Time" = $words[3].Trim('['); ` + "Method" = $words[5].Trim('"'); ` + "Page" = $words[6]; ` + "Protocol" = $words[7]; ` + "Response" = $words[8]; ` + "Referrer" = $words[10]; ` + "Client" = -join $words[11..($words.Length - 1)]; } + }# end of for loop + + return $tablerecords | Where-Object { $_.IP -ilike "10.*"} +} +$tablerecords = ApacheLogs1 +#$tablerecords diff --git a/automation-sys320/week04/WindowsApacheLogs.ps1 b/automation-sys320/week04/WindowsApacheLogs.ps1 new file mode 100644 index 0000000..8fecec6 --- /dev/null +++ b/automation-sys320/week04/WindowsApacheLogs.ps1 @@ -0,0 +1,41 @@ +# 2. list all the apache logs of XAMPP +Get-Content C:\xampp\apache\logs\access.log + +# 3. list last 5 lines of the apache logs of XAMPP +Get-Content C:\xampp\apache\logs\access.log -Tail 5 + +# 4. display only 404 and 400 errors +Get-Content C:\xampp\apache\logs\access.log | Select-String ' 404 ', ' 400 ' + +# 5. display all logs that are NOT code 200 +Get-Content C:\xampp\apache\logs\access.log | Select-String ' 200 ' + +# 6. from every file with .log extension, get those that contain the word '-error' +$A = Get-ChildItem C:\xampp\apache\logs\*.log | Select-String 'error' +# select last 5 from array +$A[-5..-1] + +# 7. display ip addresses for 404 errors +$notfounds = Get-Content C:\xampp\apache\logs\access.log | Select-String ' 404 ' +$regex = [regex] "[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}" +$ipsunorganized = $regex.Matches($notfounds) + +$ips = @() +for($i=0; $i -lt $ipsunorganized.Count; $i++){ + $ips += [pscustomobject]@{ "IP" = $ipsunorganized[$i].Value; } +} +$ips | Where-Object { $_.IP -ilike "10.*" } + +# 8. count ips from previous output +$ipsoftens = $ips | Where-Object { $_.IP -ilike "10.*" } +$counts = $ipsoftens | Group-Object IP +$counts | Select-Object Count, Name + + +# 9 +# run external script Apache-Logs.ps1 +#(Join-Path $PSScriptRoot C:\Users\champuser\SYS320\week4\Apache-Logs.ps1) +. "C:\Users\champuser\SYS320\week4\Apache-Logs.ps1" + +$ips = Apache-Logs "/*external*" "404" "Mozilla/5.0" +#$ips \ No newline at end of file diff --git a/automation-sys320/week05/HTMLElementsAndWebRequests.ps1 b/automation-sys320/week05/HTMLElementsAndWebRequests.ps1 new file mode 100644 index 0000000..ffd830d --- /dev/null +++ b/automation-sys320/week05/HTMLElementsAndWebRequests.ps1 @@ -0,0 +1,21 @@ +$scraped_page = Invoke-WebRequest -TimeoutSec 10 http://localhost/ToBeScraped.html + +# 9. get link count +#$scraped_page.Links.Count + +# 10. get the links as html elements +#$scraped_page.Links + +# 11. get the links and display only the URL and its text +#$scraped_page.Links | select outerText, href + +# 12. get out text of every element with tag h2 +#$h2s=$scraped_page.ParsedHtml.body.getElementsByTagName("h2") | select outerText +#$h2s + + +# 13. print innterText of every div element that has the class as "div-1" +$divs1=$scraped_page.ParsedHtml.body.getElementsByTagName("div") | ` +where { $_.getAttributeNode("class").value -ilike "div-1" } | select innerText + +$divs1 \ No newline at end of file diff --git a/automation-sys320/week05/ScrapingChamplainClasses.ps1 b/automation-sys320/week05/ScrapingChamplainClasses.ps1 new file mode 100644 index 0000000..65d8d8d --- /dev/null +++ b/automation-sys320/week05/ScrapingChamplainClasses.ps1 @@ -0,0 +1,47 @@ +function gatherClasses(){ + +$page = Invoke-WebRequest -TimeoutSec 2 http://localhost/Courses.html + +# get all tr elements +$trs=$page.ParsedHTML.body.getElementsByTagName("tr") + +# array to hold results +$FullTable = @() +for($i=1; $i -lt $trs.length; $i++){ + + # get every td element of current tr element + $tds= $trs[$i].getElementsByTagName("td") + + # want to seperate start time and end time from one time field + $Times = $tds[5].innerText.split(" - ") + + $FullTable += [pscustomobject]@{"Class Code" = $tds[0].innerText; ` + "Title" = $tds[1].innerText; ` + "Days" = $tds[4].innerText; ` + "Time Start" = $Times[0]; ` + "Time End" = $Times[1]; ` + "Instructor" = $tds[6].innerText; ` + "Location" = $tds[9].innerText; ` + } + }# for loop end + $Fulltable = daysTranslator($FullTable) + return $FullTable +} + + +function daysTranslator($FullTable){ + + for($i=0; $i -lt $FullTable.length; $i++){ + $Days = @() + + if($FullTable[$i].Days -ilike "M*"){ $Days += "Monday" } + if($FullTable[$i].Days -ilike "*T[TWF]*"){ $Days += "Tuesday" } + if($FullTable[$i].Days -ilike "*W*"){ $Days += "Wednesday" } + if($FullTable[$i].Days -ilike "*TH*"){ $Days += "Thursday" } + if($FullTable[$i].Days -ilike "*F*"){ $Days += "Friday" } + + $FullTable[$i].Days = $Days + }# for loop end + return $FullTable +} + diff --git a/automation-sys320/week05/ToCallGatherClasses.ps1 b/automation-sys320/week05/ToCallGatherClasses.ps1 new file mode 100644 index 0000000..06e7ac9 --- /dev/null +++ b/automation-sys320/week05/ToCallGatherClasses.ps1 @@ -0,0 +1,30 @@ +(Join-Path $PSScriptRoot .\ScrapingChamplainClasses.ps1) + +$Fulltable = gatherClasses + +# i. all classes taught by Furkan Paligu +#$Fulltable | select "Class Code", Instructor, Location, Days, "Time Start", "Time End" ` +#| where { $_."Instructor" -ilike "Furkan Paligu" } + +# ii. list all classes in JOYC 310 on Mondays, display class code and times, sort by start time +#$Fulltable | Where-Object { ($_."Location" -ilike "JOYC 310") -and ($_.days -contains "Monday")} | ` +#Sort-Object "Time Start" | ` +#Select-Object "Time Start", "Time End", "Class Code" + +# iii. create list of all instructors that teach at least one course in SYS, NET, SEC, FOR, CSI, DAT. +# sort by name and make it unique + +$ITSInstrucotrs = $Fulltable | Where-Object { ($_."Class Code" -ilike "SYS*") -or ` + ($_."Class Code" -ilike "NET*") -or ` + ($_."Class Code" -ilike "SEC*") -or ` + ($_."Class Code" -ilike "FOR*") -or ` + ($_."Class Code" -ilike "CSI*") -or ` + ($_."Class Code" -ilike "DAT*") } ` + | Sort-Object "Instructor" ` + | Select-Object "Instructor" -Unique + + +# iv. group instructors by number of classes they are teaching +# sort by num classes teaching +$FullTable | Where { $_.Instructor -in $ITSInstrucotrs.Instructor } ` + | Group-Object "Instructor" | Select-Object Count,Name | Sort-Object Count -Descending diff --git a/automation-sys320/week06/Event-Logs.ps1 b/automation-sys320/week06/Event-Logs.ps1 new file mode 100644 index 0000000..3fe2a58 --- /dev/null +++ b/automation-sys320/week06/Event-Logs.ps1 @@ -0,0 +1,97 @@ +. (Join-Path $PSScriptRoot String-Helper.ps1) +. (Join-Path $PSScriptRoot Users.ps1) + +<# ****************************** + Function: get event logs from login and logouts + Input: time back to search + Output: Array of login/out objects +****************************** #> +function getLogInAndOffs($timeBack){ + +$loginouts = Get-EventLog system -source Microsoft-Windows-Winlogon -After (Get-Date).AddDays("-"+"$timeBack") + +$loginoutsTable = @() +for($i=0; $i -lt $loginouts.Count; $i++){ + +$type = "" +if($loginouts[$i].InstanceID -eq 7001) {$type="Logon"} +if($loginouts[$i].InstanceID -eq 7002) {$type="Logoff"} + + +# Check if user exists first +$user = (New-Object System.Security.Principal.SecurityIdentifier ` + $loginouts[$i].ReplacementStrings[1]).Translate([System.Security.Principal.NTAccount]) + +$loginoutsTable += [pscustomobject]@{"Time" = $loginouts[$i].TimeGenerated; ` + "Id" = $loginouts[$i].InstanceId; ` + "Event" = $type; ` + "User" = $user; + } +} # End of for + +return $loginoutsTable +} # End of function getLogInAndOffs + + + + +<# ****************************** + Function: get windows event logs for failed logins + Input: time to search back + Output: array of failed login objects +****************************** #> +function getFailedLogins($timeBack){ + + $failedlogins = Get-EventLog security -After (Get-Date).AddDays("-"+"$timeBack") | Where { $_.InstanceID -eq "4625" } + + $failedloginsTable = @() + for($i=0; $i -lt $failedlogins.Count; $i++){ + + $account="" + $domain="" + + $usrlines = getMatchingLines $failedlogins[$i].Message "*Account Name*" + $usr = $usrlines[1].Split(":")[1].trim() + + $dmnlines = getMatchingLines $failedlogins[$i].Message "*Account Domain*" + $dmn = $dmnlines[1].Split(":")[1].trim() + + $user = $dmn+"\"+$usr; + + $failedloginsTable += [pscustomobject]@{"Time" = $failedlogins[$i].TimeGenerated; ` + "Id" = $failedlogins[$i].InstanceId; ` + "Event" = "Failed"; ` + "User" = $user; + } + + } + + return $failedloginsTable +} # End of function getFailedLogins + + + +<# ****************************************************** + Functions: get at risk users, >10 failed logins in time frame + Input: time to search back + Output: array of users & numfailedlogin objects +********************************************************* #> +function getAtRiskUsers($timeBack){ + $users = getEnabledUsers + $failedLogins = getFailedLogins $timeBack + + $atRiskUsers = @() + + for($i=0; $i -lt $users.Count; $i++){ + $name = $users[$i].Name + $failCount = ($failedLogins | Where-Object { $_.User -ilike "*$name"} ).Count + if($failCount -ge 10){ + $atRiskUsers += [pscustomobject]@{"User" = $name; ` + "Failed Logins" = $failCount; } + } + + } + + return $atRiskUsers + +} diff --git a/automation-sys320/week06/String-Helper.ps1 b/automation-sys320/week06/String-Helper.ps1 new file mode 100644 index 0000000..2ca3b39 --- /dev/null +++ b/automation-sys320/week06/String-Helper.ps1 @@ -0,0 +1,55 @@ +<# String-Helper +************************************************************* + This script contains functions that help with String/Match/Search + operations. +************************************************************* +#> + + +<# ****************************************************** + Functions: Get Matching Lines + Input: 1) Text with multiple lines + 2) Keyword + Output: 1) Array of lines that contain the keyword +********************************************************* #> +function getMatchingLines($contents, $lookline){ + +$allines = @() +$splitted = $contents.split([Environment]::NewLine) + +for($j=0; $j -lt $splitted.Count; $j++){ + + if($splitted[$j].Length -gt 0){ + if($splitted[$j] -ilike $lookline){ $allines += $splitted[$j] } + } + +} + +return $allines +} + +<# ****************************************************** + Functions: Checks if password is >6char, includes a digit, and includes a special character + Input: 1) Password + Output: 1) Boolean if password is valid +********************************************************* #> +function checkpassword($passwd){ + Write-Host $passwd + if($passwd.Length -lt 6){ + Write-Host "failed length test" | Out-String + return $false + } + elseif($passwd -notmatch "[0-9]"){ + Write-Host "Digit Test" | Out-String + return $false + } + elseif($passwd -notmatch "[!$%^@#&().-]"){ + Write-Host "special character test" | Out-String + return $false + }else{ + Write-Host "here" + return $true + } +} + +#checkpassword("abcd123!") \ No newline at end of file diff --git a/automation-sys320/week06/TurnToMenu.ps1 b/automation-sys320/week06/TurnToMenu.ps1 new file mode 100644 index 0000000..73a11fb --- /dev/null +++ b/automation-sys320/week06/TurnToMenu.ps1 @@ -0,0 +1,67 @@ +. (Join-Path $PSScriptRoot ../week4/ParsingApacheLogs.ps1) + +. (Join-Path $PSScriptRoot Users.ps1) +. (Join-Path $PSScriptRoot Event-Logs.ps1) + +clear + +$Prompt = "Please choose your operation:`n" +$Prompt += "1 - Display last 10 apache logs`n" +$Prompt += "2 - Display last 10 failed logins (all users)`n" +$Prompt += "3 - Display At Risk users`n" +$Prompt += "4 - Start Chrome`n" +$Prompt += "5 - Exit`n" + + +$operation = $true + +while($operation){ + + + Write-Host $Prompt | Out-String + $choice = Read-Host + + + if($choice -eq 5){ + Write-Host "Goodbye" | Out-String + exit + $operation = $false + } + + #display last 10 apache logs + elseif($choice -eq 1){1 + $apachelogs= ApacheLogs1 + $apachelogs[-10..-1] | Select IP, Time, Method, Page, Protocol, Response, referrer, Client | Out-String + } + + #display last 10 failed logins(all user) + elseif($choice -eq 2){ + $failedlogins = getFailedLogins 90 + $failedlogins[-10..-1] | Select Time, User | Out-String + } + + #display at risk users + elseif($choice -eq 3){ + $timeSince = Read-Host -Prompt "enter number of days to search back" + $atRiskUsers = getAtRiskUsers $timeSince + + Write-Host ($atRiskUsers | Format-Table | Out-String) + } + + # start chrome, and navigate to champlain.edu - if no instance of chrome is running + elseif($choice -eq 4){ + if(Get-Process -Name chrome -ErrorAction SilentlyContinue){ + Write-Host "Chrome Already Running." + } + else{ + Write-Host "Chrome not running. Starting now" + Start-Process 'C:\Program Files\Google\Chrome\Application\chrome.exe' ` + '--new-window https://champlain.edu' + } + } + + else{ + Write-Host "invalid input. 1-5 allowed`n" + } + +} \ No newline at end of file diff --git a/automation-sys320/week06/Users.ps1 b/automation-sys320/week06/Users.ps1 new file mode 100644 index 0000000..92ac2ae --- /dev/null +++ b/automation-sys320/week06/Users.ps1 @@ -0,0 +1,81 @@ + + +<# ****************************** +# Create a function that returns a list of NAMEs AND SIDs only for enabled users +****************************** #> +function getEnabledUsers(){ + + $enabledUsers = Get-LocalUser | Where-Object { $_.Enabled -ilike "True" } | Select-Object Name, SID + return $enabledUsers + +} + +function checkuser($name){ + $users = Get-LocalUser | Where-Object { $_.name -ilike $name } + if($users.Count -lt 1){ return $false} + else { return $true } +} + +#checkuser("champuser2") + +<# ****************************** +# Create a function that returns a list of NAMEs AND SIDs only for not enabled users +****************************** #> +function getNotEnabledUsers(){ + + $notEnabledUsers = Get-LocalUser | Where-Object { $_.Enabled -ilike "False" } | Select-Object Name, SID + return $notEnabledUsers + +} + + + + +<# ****************************** +# Create a function that adds a user +****************************** #> +function createAUser($name, $password){ + + $params = @{ + Name = $name + Password = $password + } + + $newUser = New-LocalUser @params + + + # ***** Policies ****** + + # User should be forced to change password + Set-LocalUser $newUser -PasswordNeverExpires $false + + # First time created users should be disabled + Disable-LocalUser $newUser + +} + + + +function removeAUser($name){ + + $userToBeDeleted = Get-LocalUser | Where-Object { $_.name -ilike $name } + Remove-LocalUser $userToBeDeleted + +} + + + +function disableAUser($name){ + + $userToBeDeleted = Get-LocalUser | Where-Object { $_.name -ilike $name } + Disable-LocalUser $userToBeDeleted + +} + + +function enableAUser($name){ + + $userToBeEnabled = Get-LocalUser | Where-Object { $_.name -ilike $name } + Enable-LocalUser $userToBeEnabled + +} \ No newline at end of file diff --git a/automation-sys320/week06/main.ps1 b/automation-sys320/week06/main.ps1 new file mode 100644 index 0000000..4982554 --- /dev/null +++ b/automation-sys320/week06/main.ps1 @@ -0,0 +1,157 @@ +. (Join-Path $PSScriptRoot Users.ps1) +. (Join-Path $PSScriptRoot Event-Logs.ps1) + +clear + +$Prompt = "Please choose your operation:`n" +$Prompt += "1 - List Enabled Users`n" +$Prompt += "2 - List Disabled Users`n" +$Prompt += "3 - Create a User`n" +$Prompt += "4 - Remove a User`n" +$Prompt += "5 - Enable a User`n" +$Prompt += "6 - Disable a User`n" +$Prompt += "7 - Get Log-In Logs`n" +$Prompt += "8 - Get Failed Log-In Logs`n" +$Prompt += "9 - List at Risk Users`n" +$Prompt += "0 - Exit`n" + + + +$operation = $true + +while($operation){ + + + Write-Host $Prompt | Out-String + $choice = Read-Host + + # exit + if($choice -eq 0){ + Write-Host "Goodbye" | Out-String + exit + $operation = $false + } + + # get enabled users + elseif($choice -eq 1){ + $enabledUsers = getEnabledUsers + Write-Host ($enabledUsers | Format-Table | Out-String) + } + + #get not enabled users + elseif($choice -eq 2){ + $notEnabledUsers = getNotEnabledUsers + Write-Host ($notEnabledUsers | Format-Table | Out-String) + } + + + # Create a user + elseif($choice -eq 3){ + + $name = Read-Host -Prompt "Please enter the username for the new user" + + $chkuser = checkuser $name + if($chkuser -ne $true){ # check if user already exists + $password = Read-Host -AsSecureString -Prompt "Please enter the password for the new user" + $bstr = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($password) + $plainpassword = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($bstr) + $chkPasswd = checkpassword $plainpassword + + if($chkPasswd -ne $false){ # check if password is valid + createAUser $name $password + Write-Host "User: $name is created." | Out-String + } + else{ Write-Host "invalid password" | Out-String } + + } + else { Write-Host "user already exists" | Out-String} + } + + + # Remove a user + elseif($choice -eq 4){ + + $name = Read-Host -Prompt "Please enter the username for the user to be removed" + + $chkUser = checkuser $name + if($chkUser -eq $true){# check if user already exists + removeAUser $name + Write-Host "User: $name Removed." | Out-String + } + else { Write-Host "user does not exist" | Out-String } + } + + + # Enable a user + elseif($choice -eq 5){ + + + $name = Read-Host -Prompt "Please enter the username for the user to be enabled" + + $chkUser = checkuser $name + + if($chkUser -eq $true){ # check if user already exists + enableAUser $name + Write-Host "User: $name Enabled." | Out-String + } + else { Write-Host "user does not exist" | Out-String } + + } + + + # Disable a user + elseif($choice -eq 6){ + + $name = Read-Host -Prompt "Please enter the username for the user to be disabled" + + $chkUser = checkuser $name + if($chkUser -eq $true){ # check if user already exists + disableAUser $name + Write-Host "User: $name Disabled." | Out-String + } + else{ Write-Host "user does not exist" | Out-String } + } + + # get login logs + elseif($choice -eq 7){ + + $name = Read-Host -Prompt "Please enter the username for the user logs" + + $chkUser = checkuser $name + if($chkUser -eq $true){ # check if user already exists + + $timeSince = Read-Host -Prompt "enter number of days to search back" + $userLogins = getLogInAndOffs $timeSince + + Write-Host ($userLogins | Where-Object { $_.User -ilike "*$name"} | Format-Table | Out-String) + } + else { Write-Host "user does not exist" | Out-String } + } + + # get failed login logs + elseif($choice -eq 8){ + + $name = Read-Host -Prompt "Please enter the username for the user's failed login logs" + + $chkUser = checkuser $name + if($chkUser -eq $true){ # check if user already exists + $timeSince = Read-Host -Prompt "enter number of days to search back" + $userLogins = getFailedLogins $timeSince + + Write-Host ($userLogins | Where-Object { $_.User -ilike "*$name"} | Format-Table | Out-String) + } + else { Write-Host "user does not exist" | Out-String } + } + + # get at risk users, >10 failed logins in time frame + elseif($choice -eq 9){ + $timeSince = Read-Host -Prompt "enter number of days to search back" + $atRiskUsers = getAtRiskUsers $timeSince + Write-Host ($atRiskUsers | Format-Table | Out-String) + } + + + else{ + Write-Host "invalid input: 0-9 allowed`n" | Out-String + } + diff --git a/automation-sys320/week07/Configuration.ps1 b/automation-sys320/week07/Configuration.ps1 new file mode 100644 index 0000000..a2c40d6 --- /dev/null +++ b/automation-sys320/week07/Configuration.ps1 @@ -0,0 +1,74 @@ +#10/12/24 + +function readConfiguration(){ + Set-Location "C:\Users\champuser\SYS320\week7" + $configs = (Get-Content -Path ./configuration.txt) + $days = $configs[0] + $time = $configs[1] + return [PSCustomObject]@{ + Days = $days + ExecutionTime = $time + } +} + +function changeConfiguration(){ + $daysBack = Read-Host -Prompt "Number of days for which the logs will be obtained" + if($daysBack -notmatch '^[0-9]+$'){ + Write-Host "invalid input. digits only" | Out-String + continue + } + + $executionTime = Read-Host -Prompt "Daily execution time of the script" + if($executionTime -inotmatch '^(1?[1-9]):([0-5][0-9])\s(AM|PM)$'){ + Write-Host "invalid input. digit:digitdigit am/pm allowed" | Out-String + continue + } + + "$daysBack`n$executionTime" | Set-Content ./configuration.txt + Write-Host "Configuration Changed`n" | Out-String +} + +#main loop +function configurationMenu(){ + clear + + $Prompt = "`nPlease choose your operation:`n" + $Prompt += "1 - Show Configuration`n" + $Prompt += "2 - Change Configuration`n" + $Prompt += "3 - Exit`n" + + $operation = $true + + while($operation){ + + + Write-Host $Prompt | Out-String + $choice = Read-Host + + # exit + if($choice -eq 3){ + Write-Host "Goodbye" | Out-String + exit + $operation = $false + } + + # show configuration + elseif($choice -eq 1){ + $config = readConfiguration + $config + } + + # change configuration + elseif($choice -eq 2){ + changeConfiguration + } + + else{ + Write-Host "invalid input: 1-3 allowed`n" | Out-String + } +} +} + + + +#configurationMenu \ No newline at end of file diff --git a/automation-sys320/week07/Email.ps1 b/automation-sys320/week07/Email.ps1 new file mode 100644 index 0000000..fab48c8 --- /dev/null +++ b/automation-sys320/week07/Email.ps1 @@ -0,0 +1,18 @@ +# sends an email to charlotte.croce@mymail.champlain.edu +# with one parameter for the email body +function SendAlertEmail($Body){ +$From = "charlotte.croce@mymail.champlain.edu" +$To = "charlotte.croce@mymail.champlain.edu" +$Subject = "Suspicious Activity" + +# remove password before publishing to GitHub! +# ...and if you accidentally push with the password visible, just delete the appKey +$Password = "insert-new-appkey-here" | ConvertTo-SecureString -AsPlainText -Force +$Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $From, $Password + +Send-MailMessage -From $From -To $To -Subject $Subject -Body $Body -SmtpServer "smtp.gmail.com" ` +-Port 587 -UseSsl -Credential $Credential + +} + +#SendAlertEmail "test email body" \ No newline at end of file diff --git a/automation-sys320/week07/Email.ps1.orig b/automation-sys320/week07/Email.ps1.orig new file mode 100644 index 0000000..270f887 --- /dev/null +++ b/automation-sys320/week07/Email.ps1.orig @@ -0,0 +1,27 @@ +# sends an email to charlotte.croce@mymail.champlain.edu +# with one parameter for the email body +function SendAlertEmail($Body){ +$From = "charlotte.croce@mymail.champlain.edu" +$To = "charlotte.croce@mymail.champlain.edu" +$Subject = "Suspicious Activity" + +# remove password before publishing to GitHub! +<<<<<<< HEAD +<<<<<<< HEAD +# ...and if you accidentally push with the password visible, just delete the appKey +$Password = "insert-new-appkey-here" | ConvertTo-SecureString -AsPlainText -Force +======= +$Password = "xxxx" | ConvertTo-SecureString -AsPlainText -Force +>>>>>>> 2a39cde6cba8cf89a13018201ce592d875e1409e +======= +# ...and if you accidentally push with the password visible, just delete the appKey +$Password = "insert-new-appkey-here" | ConvertTo-SecureString -AsPlainText -Force +>>>>>>> 25c575397b1c76c4310e671c9a2bd7a2e53bf60a +$Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $From, $Password + +Send-MailMessage -From $From -To $To -Subject $Subject -Body $Body -SmtpServer "smtp.gmail.com" ` +-Port 587 -UseSsl -Credential $Credential + +} + +#SendAlertEmail "test email body" diff --git a/automation-sys320/week07/Scheduler.ps1 b/automation-sys320/week07/Scheduler.ps1 new file mode 100644 index 0000000..97c23ff --- /dev/null +++ b/automation-sys320/week07/Scheduler.ps1 @@ -0,0 +1,45 @@ +<# ****************************************************** + Functions: Creates a new scheduled task for week7/main.ps1 to run + Input: 1) Time for shceduled task to run +********************************************************* #> +function ChooseTimeToRun($Time){ +$scheduledTask = Get-ScheduledTask | Where-Object { $_.TaskName -ilike "mytask" } + +if($scheduledTask -ne $null){ + Write-Host "The task already exists" | Out-String + DisableAutoRun +} + +Write-Host "Creating new task" | Out-String + +$action = New-ScheduledTaskAction -Execute "powershell.exe" ` + -Argument "-File `"C:\Users\champuser\SYS320\week7\main.ps1`"" +$trigger = New-ScheduledTaskTrigger -Daily -At $Time +$principal = New-ScheduledTaskPrincipal -UserId 'champuser' -RunLevel Highest +$settings = New-ScheduledTaskSettingsSet -RunOnlyIfNetworkAvailable -WakeToRun +$task = New-ScheduledTask -Action $action -Principal $principal -Trigger $trigger -Settings $settings + +Register-ScheduledTask 'myTask' -InputObject $task + +Get-ScheduledTask | Where-Object { $_.TaskName -ilike "myTask" } + +} + +<# ****************************************************** + Functions: if "myTask is running", unregister it +********************************************************* #> +function DisableAutoRun(){ + +$scheduledTasks = Get-ScheduledTask | Where-Object { $_.TaskName -ilike "myTask" } + +if($scheduledTasks -ne $null){ + Write-Host "Unregistering the task." | Out-String + Unregister-ScheduledTask -TaskName 'myTask' -Confirm:$false +} + +else{ + Write-Host "The task is not registered" | Out-String +} + + +} \ No newline at end of file diff --git a/automation-sys320/week07/configuration.txt b/automation-sys320/week07/configuration.txt new file mode 100644 index 0000000..3adbf06 --- /dev/null +++ b/automation-sys320/week07/configuration.txt @@ -0,0 +1,2 @@ +90 +2:38 PM diff --git a/automation-sys320/week07/main.ps1 b/automation-sys320/week07/main.ps1 new file mode 100644 index 0000000..ec88507 --- /dev/null +++ b/automation-sys320/week07/main.ps1 @@ -0,0 +1,17 @@ +. "C:\Users\champuser\SYS320\week6\Event-Logs.ps1" +. "C:\Users\champuser\SYS320\week7\Configuration.ps1" +. "C:\Users\champuser\SYS320\week7\Email.ps1" +. "C:\Users\champuser\SYS320\week7\Scheduler.ps1" + +# obtain configuration, from Configurations.ps1 +$configuration = readConfiguration + +# call atRiskUsers using days obtained from the config file, from Event-logs.ps1 +$Failed = getAtRiskUsers $configuration.Days + +# sending at risk users as email, from Email.ps1 +SendAlertEmail ($Failed | Format-Table | Out-String) + +# setting the script to be run daily, from Scheduler.ps1 +ChooseTimeToRun($configuration.ExecutionTime) + diff --git a/automation-sys320/week08/Midterm.ps1 b/automation-sys320/week08/Midterm.ps1 new file mode 100644 index 0000000..849387d --- /dev/null +++ b/automation-sys320/week08/Midterm.ps1 @@ -0,0 +1,67 @@ + +# 1. Function to get IOC table from the given web page +function getIOCTable(){ + + $page = Invoke-WebRequest -TimeoutSec 10 http://10.0.17.5/IOC.html + + # get all tr elements + $trs=$page.ParsedHTML.body.getElementsByTagName("tr") + + # array to hold results + $IOCTable = @() + for($i=1; $i -lt $trs.length; $i++){ + # get every td element of current tr element + $tds= $trs[$i].getElementsByTagName("td") + $IOCTable += [pscustomobject]@{"Pattern" = $tds[0].innerText; "Explanation" = $tds[1].innerText; } + }# for loop end + + return $IOCTable +} # function end + +# getIOCTable | Format-Table + +# 2. function to get Apache Access logs +function getApacheLogs(){ + $logs = Get-Content "C:\Users\champuser\SYS320\week8\access.log" + $logTable = @() + + for($i=0; $i -lt $logs.Length; $i++){ + + # split string into words + $words = $logs[$i] -split " " + + $logTable += [pscustomobject]@{"IP" = $words[0]; ` + "Time" = $words[3].Trim('['); ` + "Method" = $words[5].Trim('"'); ` + "Page" = $words[6]; ` + "Protocol" = $words[7]; ` + "Response" = $words[8]; ` + "Referrer" = $words[10]; ` } + }# for loop end + + return $logTable +} # function end + +# getApacheLogs | Format-Table + + +# 3. get Apache logs, but only display those that have an IOC in the page field +function getIOCLogs(){ + $logTable = getApacheLogs + $IOCTable = getIOCTable + + $IOCLogTable = @() + for($i = 0; $i -lt $logTable.Count; $i++){ + for($j = 0; $j -lt $IOCTable.Count; $j++){ + if ($logTable[$i].Page -match $IOCTable[$j].Pattern){ + $IOCLogTable += $logTable[$i] + } # if end + } # inner for loop end + } # outer for loop end + + return $IOCLogTable + +} # function end + +getIOCLogs | Format-Table + diff --git a/automation-sys320/week08/access.log b/automation-sys320/week08/access.log new file mode 100644 index 0000000..3d6ee9f --- /dev/null +++ b/automation-sys320/week08/access.log @@ -0,0 +1,20 @@ +10.0.17.5 - - [04/Mar/2024:13:28:46 -0500] "GET /index.html HTTP/1.1" 404 295 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36" +10.0.17.5 - - [04/Mar/2024:13:29:21 -0500] "GET /index.html HTTP/1.1" 200 758 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36" +10.0.17.5 - - [04/Mar/2024:14:42:42 -0500] "GET /index.php HTTP/1.1" 404 295 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36" +10.0.17.5 - - [04/Mar/2024:14:43:07 -0500] "GET /index.php HTTP/1.1" 200 758 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36" +10.0.17.5 - - [04/Mar/2024:14:43:21 -0500] "GET /index.php?a=1&b=2 HTTP/1.1" 200 758 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36" +10.0.17.5 - - [04/Mar/2024:14:43:50 -0500] "GET /index.php?cmd=etc/passwd HTTP/1.1" 200 758 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36" +10.0.17.5 - - [04/Mar/2024:14:44:19 -0500] "GET /index.php?cmd=cat+etc/passwd HTTP/1.1" 200 758 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36" +10.0.17.5 - - [04/Mar/2024:14:44:52 -0500] "GET /index.php?cmd=/bing/bash+myscript.bash HTTP/1.1" 200 758 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36" +10.0.17.5 - - [04/Mar/2024:14:45:01 -0500] "GET /index.php?cmd=/bin/bash+myscript.bash HTTP/1.1" 200 758 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36" +10.0.17.5 - - [04/Mar/2024:14:45:19 -0500] "GET /index.php?cmd=/bin/sh+simplebackdoor.bash HTTP/1.1" 200 758 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36" +10.0.17.5 - - [04/Mar/2024:14:45:31 -0500] "GET /index.php?/bin/sh+simplebackdoor.bash HTTP/1.1" 200 758 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36" +10.0.17.5 - - [04/Mar/2024:14:46:03 -0500] "GET /index.php?a=1+OR+1=1-- HTTP/1.1" 200 758 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36" +10.0.17.5 - - [04/Mar/2024:14:46:12 -0500] "GET /index.php?a=1+OR+1=1- HTTP/1.1" 200 758 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36" +10.0.17.5 - - [04/Mar/2024:14:46:27 -0500] "GET /index.php?a=1+OR+1=1 HTTP/1.1" 200 758 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36" +10.0.17.5 - - [04/Mar/2024:14:46:47 -0500] "GET /index.php?word=Hello+World HTTP/1.1" 200 758 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36" +10.0.17.6 - - [04/Mar/2024:14:48:39 -0500] "GET / HTTP/1.1" 200 758 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:123.0) Gecko/20100101 Firefox/123.0" +10.0.17.6 - - [04/Mar/2024:14:48:40 -0500] "GET /favicon.ico HTTP/1.1" 404 295 "http://10.0.17.5/" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:123.0) Gecko/20100101 Firefox/123.0" +10.0.17.6 - - [04/Mar/2024:14:48:50 -0500] "GET /index.html HTTP/1.1" 200 758 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:123.0) Gecko/20100101 Firefox/123.0" +10.0.17.6 - - [04/Mar/2024:14:49:44 -0500] "GET /index.html?command=/bin/bash/+reverseshell.bash HTTP/1.1" 200 758 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:123.0) Gecko/20100101 Firefox/123.0" +10.0.17.6 - - [04/Mar/2024:14:50:24 -0500] "GET /index.html?command=/bin/bash/+midtermcheatdetector.bash HTTP/1.1" 200 758 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:123.0) Gecko/20100101 Firefox/123.0" \ No newline at end of file diff --git a/automation-sys320/week09/IPList.bash b/automation-sys320/week09/IPList.bash new file mode 100644 index 0000000..a285709 --- /dev/null +++ b/automation-sys320/week09/IPList.bash @@ -0,0 +1,20 @@ +#!/bin/bash + +# list all ips in given network prefix, /24 only + + +# usage: bash IPList.bash 10.0.17 +[ $# -lt 1 ] && echo "Usage: $0 " && exit 1 + +#prefix is the first input taken +prefix=$1 + +[ ${#prefix} -lt 5 ] && \ +printf "Prefix length is too short\nPrefix example: 10.0.17\n" && \ +exit 1 + +for i in {1..254} +do + ping -c 1 $prefix.$i | grep "64 bytes from *" | \ + grep -o $prefix.$i +done diff --git a/automation-sys320/week09/myIP.bash b/automation-sys320/week09/myIP.bash new file mode 100644 index 0000000..c5a1074 --- /dev/null +++ b/automation-sys320/week09/myIP.bash @@ -0,0 +1,11 @@ +#!/bin/bash + +# display ONLY IP address +# output ip addr command +# grep for enabled interfaces +# grep to narrow in on IP +# use tr to delete extra letters and spaces from output +ip address | grep 'state UP' -A 3 | grep -o 'inet.*brd' | tr -d 'a-z ' + + + diff --git a/automation-sys320/week10/basic_access_intruder.bash b/automation-sys320/week10/basic_access_intruder.bash new file mode 100644 index 0000000..bfaf7e8 --- /dev/null +++ b/automation-sys320/week10/basic_access_intruder.bash @@ -0,0 +1,6 @@ +#!/bin/bash + +for i in {1..20} +do + curl 10.0.17.8 +done diff --git a/automation-sys320/week10/lecture.bash b/automation-sys320/week10/lecture.bash new file mode 100644 index 0000000..06f0b16 --- /dev/null +++ b/automation-sys320/week10/lecture.bash @@ -0,0 +1,14 @@ +#!/bin/bash + +file="/var/log/apache2/access.log" + +results=$(cat $file | cut -d' ' -f1,7 | tr -d "[") + +function pageCount(){ + counts=$(awk '{print $7}' $file | sort | uniq -c) +} + +pageCount +echo "$counts" + +#echo "$results" diff --git a/automation-sys320/week10/lecture2.bash b/automation-sys320/week10/lecture2.bash new file mode 100644 index 0000000..60bd837 --- /dev/null +++ b/automation-sys320/week10/lecture2.bash @@ -0,0 +1,9 @@ +#!/bin/bash + +function countingCurlAccess(){ + file="/var/log/apache2/access.log" + curlCounts=$(cat "$file" | cut -d' ' -f1,12 | grep "curl" | uniq -c) +} + +countingCurlAccess +echo "$curlCounts" diff --git a/automation-sys320/week11/IOC.txt b/automation-sys320/week11/IOC.txt new file mode 100644 index 0000000..f1acb69 --- /dev/null +++ b/automation-sys320/week11/IOC.txt @@ -0,0 +1,6 @@ +etc/passwd +cmd= +/bin/bash +/bin/sh +1=1# +1=1-- diff --git a/automation-sys320/week11/access.txt b/automation-sys320/week11/access.txt new file mode 100644 index 0000000..c2bdb34 --- /dev/null +++ b/automation-sys320/week11/access.txt @@ -0,0 +1,81 @@ +10.0.17.12 - - [17/Nov/2024:09:41:57 -0500] "GET / HTTP/1.1" 200 481 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36" +10.0.17.12 - - [17/Nov/2024:09:41:57 -0500] "GET /favicon.ico HTTP/1.1" 404 487 "http://10.0.17.8/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36" +10.0.17.12 - - [17/Nov/2024:09:42:00 -0500] "GET /page1.html HTTP/1.1" 200 485 "http://10.0.17.8/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36" +10.0.17.12 - - [17/Nov/2024:09:42:01 -0500] "GET /index.html HTTP/1.1" 200 480 "http://10.0.17.8/page1.html" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36" +10.0.17.12 - - [17/Nov/2024:09:42:01 -0500] "GET /page2.html HTTP/1.1" 200 483 "http://10.0.17.8/index.html" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36" +10.0.17.12 - - [17/Nov/2024:09:42:51 -0500] "-" 408 0 "-" "-" +10.0.17.12 - - [17/Nov/2024:10:30:19 -0500] "GET /etc/passwd HTTP/1.1" 404 488 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36" +10.0.17.12 - - [17/Nov/2024:10:30:22 -0500] "GET /etc/passwd HTTP/1.1" 404 487 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36" +10.0.17.12 - - [17/Nov/2024:10:30:23 -0500] "GET /etc/passwd HTTP/1.1" 404 487 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36" +10.0.17.12 - - [17/Nov/2024:10:30:31 -0500] "GET /1=1-- HTTP/1.1" 404 488 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36" +10.0.17.12 - - [17/Nov/2024:10:30:32 -0500] "GET /1=1-- HTTP/1.1" 404 487 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36" +10.0.17.12 - - [17/Nov/2024:10:30:43 -0500] "GET //bin/bash HTTP/1.1" 404 488 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36" +10.0.17.8 - - [17/Nov/2024:10:30:55 -0500] "GET /cmd=ls HTTP/1.1" 404 488 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.0.0 Safari/537.36" +10.0.17.8 - - [17/Nov/2024:10:30:57 -0500] "GET /cmd=ls HTTP/1.1" 404 487 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.0.0 Safari/537.36" +10.0.17.12 - - [17/Nov/2024:10:31:35 -0500] "-" 408 0 "-" "-" +10.0.17.8 - - [04/Nov/2024:11:36:51 -0500] "GET / HTTP/1.1" 200 3460 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.0.0 Safari/537.36" +10.0.17.8 - - [04/Nov/2024:11:36:51 -0500] "GET /icons/ubuntu-logo.png HTTP/1.1" 200 3607 "http://10.0.17.8/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.0.0 Safari/537.36" +10.0.17.8 - - [04/Nov/2024:11:36:51 -0500] "GET /favicon.ico HTTP/1.1" 404 487 "http://10.0.17.8/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.0.0 Safari/537.36" +10.0.17.8 - - [04/Nov/2024:11:37:42 -0500] "-" 408 0 "-" "-" +10.0.17.8 - - [04/Nov/2024:11:43:51 -0500] "GET / HTTP/1.1" 200 478 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.0.0 Safari/537.36" +10.0.17.8 - - [04/Nov/2024:11:43:51 -0500] "GET / HTTP/1.1" 200 477 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.0.0 Safari/537.36" +10.0.17.8 - - [04/Nov/2024:11:43:53 -0500] "GET /page1.html HTTP/1.1" 200 478 "http://10.0.17.8/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.0.0 Safari/537.36" +10.0.17.8 - - [04/Nov/2024:11:43:54 -0500] "GET /index.html HTTP/1.1" 200 477 "http://10.0.17.8/page1.html" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.0.0 Safari/537.36" +10.0.17.8 - - [04/Nov/2024:11:43:55 -0500] "GET /page2.html HTTP/1.1" 200 478 "http://10.0.17.8/index.html" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.0.0 Safari/537.36" +10.0.17.8 - - [04/Nov/2024:11:43:56 -0500] "GET /page2.html HTTP/1.1" 200 478 "http://10.0.17.8/page2.html" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.0.0 Safari/537.36" +10.0.17.8 - - [04/Nov/2024:11:43:57 -0500] "GET /page2.html HTTP/1.1" 200 478 "http://10.0.17.8/page2.html" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.0.0 Safari/537.36" +10.0.17.8 - - [04/Nov/2024:11:44:14 -0500] "GET /index.html HTTP/1.1" 200 478 "http://10.0.17.8/page2.html" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.0.0 Safari/537.36" +10.0.17.8 - - [04/Nov/2024:11:44:15 -0500] "GET /page2.html HTTP/1.1" 200 479 "http://10.0.17.8/index.html" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.0.0 Safari/537.36" +10.0.17.8 - - [04/Nov/2024:11:44:16 -0500] "GET /page1.html HTTP/1.1" 200 478 "http://10.0.17.8/page2.html" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.0.0 Safari/537.36" +10.0.17.8 - - [04/Nov/2024:11:45:05 -0500] "-" 408 0 "-" "-" +10.0.17.8 - - [04/Nov/2024:11:45:18 -0500] "GET /index.html HTTP/1.1" 200 481 "http://10.0.17.8/page1.html" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.0.0 Safari/537.36" +10.0.17.8 - - [04/Nov/2024:11:45:19 -0500] "GET /page2.html HTTP/1.1" 200 483 "http://10.0.17.8/index.html" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.0.0 Safari/537.36" +10.0.17.8 - - [04/Nov/2024:11:45:20 -0500] "GET /index.html HTTP/1.1" 200 480 "http://10.0.17.8/page2.html" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.0.0 Safari/537.36" +10.0.17.8 - - [04/Nov/2024:11:45:21 -0500] "GET /page1.html HTTP/1.1" 200 483 "http://10.0.17.8/index.html" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.0.0 Safari/537.36" +10.0.17.8 - - [04/Nov/2024:11:45:23 -0500] "GET /index.html HTTP/1.1" 200 480 "http://10.0.17.8/page2.html" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.0.0 Safari/537.36" +10.0.17.8 - - [04/Nov/2024:11:45:24 -0500] "GET /page1.html HTTP/1.1" 200 483 "http://10.0.17.8/index.html" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.0.0 Safari/537.36" +10.0.17.8 - - [04/Nov/2024:11:45:40 -0500] "GET /index.html HTTP/1.1" 200 481 "http://10.0.17.8/page1.html" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.0.0 Safari/537.36" +10.0.17.8 - - [04/Nov/2024:11:45:41 -0500] "GET /page1.html HTTP/1.1" 200 484 "http://10.0.17.8/index.html" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.0.0 Safari/537.36" +10.0.17.8 - - [04/Nov/2024:11:45:42 -0500] "GET /index.html HTTP/1.1" 200 480 "http://10.0.17.8/page1.html" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.0.0 Safari/537.36" +10.0.17.8 - - [04/Nov/2024:11:46:32 -0500] "-" 408 0 "-" "-" +10.0.17.8 - - [04/Nov/2024:11:48:03 -0500] "GET / HTTP/1.1" 200 449 "-" "curl/7.81.0" +10.0.17.8 - - [04/Nov/2024:11:59:51 -0500] "GET / HTTP/1.1" 200 449 "-" "curl/7.81.0" +10.0.17.8 - - [04/Nov/2024:11:59:51 -0500] "GET / HTTP/1.1" 200 449 "-" "curl/7.81.0" +10.0.17.8 - - [04/Nov/2024:11:59:51 -0500] "GET / HTTP/1.1" 200 449 "-" "curl/7.81.0" +10.0.17.8 - - [04/Nov/2024:11:59:51 -0500] "GET / HTTP/1.1" 200 449 "-" "curl/7.81.0" +10.0.17.8 - - [04/Nov/2024:11:59:51 -0500] "GET / HTTP/1.1" 200 449 "-" "curl/7.81.0" +10.0.17.8 - - [04/Nov/2024:11:59:51 -0500] "GET / HTTP/1.1" 200 449 "-" "curl/7.81.0" +10.0.17.8 - - [04/Nov/2024:11:59:51 -0500] "GET / HTTP/1.1" 200 449 "-" "curl/7.81.0" +10.0.17.8 - - [04/Nov/2024:11:59:51 -0500] "GET / HTTP/1.1" 200 449 "-" "curl/7.81.0" +10.0.17.8 - - [04/Nov/2024:11:59:51 -0500] "GET / HTTP/1.1" 200 449 "-" "curl/7.81.0" +10.0.17.8 - - [04/Nov/2024:11:59:51 -0500] "GET / HTTP/1.1" 200 449 "-" "curl/7.81.0" +10.0.17.8 - - [04/Nov/2024:11:59:51 -0500] "GET / HTTP/1.1" 200 449 "-" "curl/7.81.0" +10.0.17.8 - - [04/Nov/2024:11:59:51 -0500] "GET / HTTP/1.1" 200 449 "-" "curl/7.81.0" +10.0.17.8 - - [04/Nov/2024:11:59:51 -0500] "GET / HTTP/1.1" 200 449 "-" "curl/7.81.0" +10.0.17.8 - - [04/Nov/2024:11:59:51 -0500] "GET / HTTP/1.1" 200 449 "-" "curl/7.81.0" +10.0.17.8 - - [04/Nov/2024:11:59:51 -0500] "GET / HTTP/1.1" 200 449 "-" "curl/7.81.0" +10.0.17.8 - - [04/Nov/2024:11:59:51 -0500] "GET / HTTP/1.1" 200 449 "-" "curl/7.81.0" +10.0.17.8 - - [04/Nov/2024:11:59:51 -0500] "GET / HTTP/1.1" 200 449 "-" "curl/7.81.0" +10.0.17.8 - - [04/Nov/2024:11:59:51 -0500] "GET / HTTP/1.1" 200 449 "-" "curl/7.81.0" +10.0.17.8 - - [04/Nov/2024:11:59:51 -0500] "GET / HTTP/1.1" 200 449 "-" "curl/7.81.0" +10.0.17.8 - - [04/Nov/2024:11:59:51 -0500] "GET / HTTP/1.1" 200 449 "-" "curl/7.81.0" +10.0.17.8 - - [04/Nov/2024:12:01:57 -0500] "GET / HTTP/1.1" 200 449 "-" "curl/7.81.0" +10.0.17.8 - - [04/Nov/2024:12:01:57 -0500] "GET / HTTP/1.1" 200 449 "-" "curl/7.81.0" +10.0.17.8 - - [04/Nov/2024:12:01:57 -0500] "GET / HTTP/1.1" 200 449 "-" "curl/7.81.0" +10.0.17.8 - - [04/Nov/2024:12:01:57 -0500] "GET / HTTP/1.1" 200 449 "-" "curl/7.81.0" +10.0.17.8 - - [04/Nov/2024:12:01:57 -0500] "GET / HTTP/1.1" 200 449 "-" "curl/7.81.0" +10.0.17.8 - - [04/Nov/2024:12:01:57 -0500] "GET / HTTP/1.1" 200 449 "-" "curl/7.81.0" +10.0.17.8 - - [04/Nov/2024:12:01:57 -0500] "GET / HTTP/1.1" 200 449 "-" "curl/7.81.0" +10.0.17.8 - - [04/Nov/2024:12:01:57 -0500] "GET / HTTP/1.1" 200 449 "-" "curl/7.81.0" +10.0.17.8 - - [04/Nov/2024:12:01:57 -0500] "GET / HTTP/1.1" 200 449 "-" "curl/7.81.0" +10.0.17.8 - - [04/Nov/2024:12:01:57 -0500] "GET / HTTP/1.1" 200 449 "-" "curl/7.81.0" +10.0.17.8 - - [04/Nov/2024:12:01:57 -0500] "GET / HTTP/1.1" 200 449 "-" "curl/7.81.0" +10.0.17.8 - - [04/Nov/2024:12:01:57 -0500] "GET / HTTP/1.1" 200 449 "-" "curl/7.81.0" +10.0.17.8 - - [04/Nov/2024:12:01:57 -0500] "GET / HTTP/1.1" 200 449 "-" "curl/7.81.0" +10.0.17.8 - - [04/Nov/2024:12:01:57 -0500] "GET / HTTP/1.1" 200 449 "-" "curl/7.81.0" +10.0.17.8 - - [04/Nov/2024:12:01:57 -0500] "GET / HTTP/1.1" 200 449 "-" "curl/7.81.0" +10.0.17.8 - - [04/Nov/2024:12:01:57 -0500] "GET / HTTP/1.1" 200 449 "-" "curl/7.81.0" +10.0.17.8 - - [04/Nov/2024:12:01:57 -0500] "GET / HTTP/1.1" 200 449 "-" "curl/7.81.0" +10.0.17.8 - - [04/Nov/2024:12:01:57 -0500] "GET / HTTP/1.1" 200 449 "-" "curl/7.81.0" +10.0.17.8 - - [04/Nov/2024:12:01:57 -0500] "GET / HTTP/1.1" 200 449 "-" "curl/7.81.0" +10.0.17.8 - - [04/Nov/2024:12:01:57 -0500] "GET / HTTP/1.1" 200 449 "-" "curl/7.81.0" diff --git a/automation-sys320/week11/apacheLogMenu.bash b/automation-sys320/week11/apacheLogMenu.bash new file mode 100644 index 0000000..7cdcf7d --- /dev/null +++ b/automation-sys320/week11/apacheLogMenu.bash @@ -0,0 +1,115 @@ +#! /bin/bash + +#logFile="/var/log/apache2/access.log.1" +logFile="access.txt" + +if [[ ! -f "${logFile}" ]] +then + bash getLogs.bash +fi + +function displayAllLogs(){ + cat "$logFile" +} + +function displayOnlyIPs(){ + cat "$logFile" | cut -d ' ' -f 1 | sort -n | uniq -c +} + +function displayOnlyPages(){ + cat "$logFile" | cut -d ' ' -f 7 | sort -n | uniq -c +} + +function frequentVisitors(){ + histogram | awk '$1 > 10' #visits > 10 +} + +function suspiciousVisitors(){ + cat "$logFile" | cut -d ' ' -f 1,7 | egrep -i -f IOC.txt | uniq -c +} + +function histogram(){ + + local visitsPerDay=$(cat "$logFile" | cut -d " " -f 4,1 | tr -d '[' | sort \ + | uniq) + # This is for debugging, print here to see what it does to continue: + # echo "$visitsPerDay" + + :> newtemp.txt # what :> does is in slides + echo "$visitsPerDay" | while read -r line; + do + local withoutHours=$(echo "$line" | cut -d " " -f 2 \ + | cut -d ":" -f 1) + local IP=$(echo "$line" | cut -d " " -f 1) + + local newLine="$IP $withoutHours" + echo "$IP $withoutHours" >> newtemp.txt + done + cat "newtemp.txt" | sort -n | uniq -c +} + +# function: frequentVisitors: +# Only display the IPs that have more than 10 visits +# You can either call histogram and process the results, +# Or make a whole new function. Do not forget to separate the +# number and check with a condition whether it is greater than 10 +# the output should be almost identical to histogram +# only with daily number of visits that are greater than 10 + +# function: suspiciousVisitors +# Manually make a list of indicators of attack (ioc.txt) +# filter the records with this indicators of attack +# only display the unique count of IP addresses. +# Hint: there are examples in slides + +# Keep in mind that I have selected long way of doing things to +# demonstrate loops, functions, etc. If you can do things simpler, +# it is welcomed. + +while : +do + echo "PLease select an option:" + echo "[1] Display all Logs" + echo "[2] Display only IPS" + echo "[3] Display only pages visited" + echo "[4] Histogram" + echo "[5] Frequent visitors" + echo "[6] Suspicious visitors" + echo "[7] Quit" + + read userInput + echo "" + + if [[ "$userInput" == "7" ]]; then + echo "Goodbye" + break + + elif [[ "$userInput" == "1" ]]; then + echo "Displaying all logs:" + displayAllLogs + + elif [[ "$userInput" == "2" ]]; then + echo "Displaying only IPS:" + displayOnlyIPs + + elif [[ "$userInput" == "3" ]]; then + echo "Displaying only pages visited:" + displayOnlyPages + + elif [[ "$userInput" == "4" ]]; then + echo "Histogram:" + histogram + + elif [[ "$userInput" == "5" ]]; then + echo "Displaying frequent visitors:" + frequentVisitors + + elif [[ "$userInput" == "6" ]]; then + echo "Displaying suspicious visitors:" + suspiciousVisitors + else + echo "Invalid input [1-7 allowed]" + continue + fi +done + diff --git a/automation-sys320/week11/getLogs.bash b/automation-sys320/week11/getLogs.bash new file mode 100644 index 0000000..1c66bf7 --- /dev/null +++ b/automation-sys320/week11/getLogs.bash @@ -0,0 +1,14 @@ +#!/bin/bash + +logDir="/var/log/apache2/" +allLogs=$(ls "${logDir}" | grep "access.log" | grep -v "other_vhosts") +echo "${allLogs}" + +:> access.txt + +for i in ${allLogs} +do + cat "${logDir}${i}" >> access.txt +done + + diff --git a/automation-sys320/week11/newtemp.txt b/automation-sys320/week11/newtemp.txt new file mode 100644 index 0000000..eac416d --- /dev/null +++ b/automation-sys320/week11/newtemp.txt @@ -0,0 +1,38 @@ +10.0.17.12 17/Nov/2024 +10.0.17.12 17/Nov/2024 +10.0.17.12 17/Nov/2024 +10.0.17.12 17/Nov/2024 +10.0.17.12 17/Nov/2024 +10.0.17.12 17/Nov/2024 +10.0.17.12 17/Nov/2024 +10.0.17.12 17/Nov/2024 +10.0.17.12 17/Nov/2024 +10.0.17.12 17/Nov/2024 +10.0.17.12 17/Nov/2024 +10.0.17.8 04/Nov/2024 +10.0.17.8 04/Nov/2024 +10.0.17.8 04/Nov/2024 +10.0.17.8 04/Nov/2024 +10.0.17.8 04/Nov/2024 +10.0.17.8 04/Nov/2024 +10.0.17.8 04/Nov/2024 +10.0.17.8 04/Nov/2024 +10.0.17.8 04/Nov/2024 +10.0.17.8 04/Nov/2024 +10.0.17.8 04/Nov/2024 +10.0.17.8 04/Nov/2024 +10.0.17.8 04/Nov/2024 +10.0.17.8 04/Nov/2024 +10.0.17.8 04/Nov/2024 +10.0.17.8 04/Nov/2024 +10.0.17.8 04/Nov/2024 +10.0.17.8 04/Nov/2024 +10.0.17.8 04/Nov/2024 +10.0.17.8 04/Nov/2024 +10.0.17.8 04/Nov/2024 +10.0.17.8 04/Nov/2024 +10.0.17.8 04/Nov/2024 +10.0.17.8 04/Nov/2024 +10.0.17.8 04/Nov/2024 +10.0.17.8 17/Nov/2024 +10.0.17.8 17/Nov/2024 diff --git a/automation-sys320/week13/assignment1.bash b/automation-sys320/week13/assignment1.bash new file mode 100644 index 0000000..cc3a1b9 --- /dev/null +++ b/automation-sys320/week13/assignment1.bash @@ -0,0 +1,109 @@ +#! /bin/bash +clear + +# filling courses.txt +bash courses.bash + +courseFile="courses.txt" + +function displayCoursesofInst(){ + +echo -n "Please Input an Instructor Full Name: " +read instName + +echo "" +echo "Courses of $instName :" +cat "$courseFile" | grep "$instName" | cut -d';' -f1,2 | \ +sed 's/;/ | /g' +echo "" + +} + +function courseCountofInsts(){ + +echo "" +echo "Course-Instructor Distribution" +cat "$courseFile" | cut -d';' -f7 | \ +grep -v "/" | grep -v "\.\.\." | \ +sort -n | uniq -c | sort -n -r +echo "" + +} + +# TODO - 1 +# Make a function that displays all the courses in given location +# function dislaplays course code, course name, course days, time, instructor +# Add function to the menu +# Example input: JOYC 310 +# Example output: See the screenshots in canvas + +function displayCoursesofRoom(){ + echo "" + echo -n "Input Classroom (ex JOYC 310): " + read classroom + + echo "courses in $classroom:" + cat "$courseFile" | grep "$classroom" | \ + cut -d';' -f1,2,5,6,7 | sed 's/;/ | /g' | \ + sort -n + +echo "" +} + +#TODO - 2 +# Make a function that displays all the courses that has availability +# (seat number will be more than 0) for the given course code +# Add function to the menu +# Example input: SEC +# Example output: See the screenshots in canvas + + +function displayAvailableCoursesofSubj(){ + echo "" + echo -n "Input Course code (ex SEC): " + read courseCode + + echo "available $courseCode courses:" + cat "$courseFile" | grep "$courseCode" | \ + awk -F';' '$4 > 0' | sed 's/;/ | /g' | \ + sort -n + + echo "" + +} + + +while : +do + echo "" + echo "Please select and option:" + echo "[1] Display courses of an instructor" + echo "[2] Display course count of instructors" + echo "[3] Display courses of a classroom" + echo "[4] Display available courses of subject" + echo "[5] Exit" + + read userInput + echo "" + + if [[ "$userInput" == "5" ]]; then + echo "Goodbye" + break + + elif [[ "$userInput" == "1" ]]; then + displayCoursesofInst + + elif [[ "$userInput" == "2" ]]; then + courseCountofInsts + + elif [[ "$userInput" == "3" ]]; then + displayCoursesofRoom + + elif [[ "$userInput" == "4" ]]; then + displayAvailableCoursesofSubj + + else + echo "Invalid Input. Allowed: [1-5]" + + fi +done diff --git a/automation-sys320/week13/courses.bash b/automation-sys320/week13/courses.bash new file mode 100644 index 0000000..8d65b7b --- /dev/null +++ b/automation-sys320/week13/courses.bash @@ -0,0 +1,30 @@ +#! /bin/bash + +# This is the link we will scrape +link="10.0.17.6/cc.html" + +# get it with curl and tell curl not to give errors +fullPage=$(curl -sL "$link") + +# Utilizing xmlstarlet tool to extract table from the page +toolOutput=$(echo "$fullPage" | \ +xmlstarlet format --html --recover 2>/dev/null | \ +xmlstarlet select --template --copy-of \ +"//html//body//div//div//table//tr") + +# Processing HTML with sed +# 1- Replacing every with a line break +echo "$toolOutput" | sed 's/<\/tr>/\n/g' | \ + sed -e 's/&//g' | \ + sed -e 's///g' | \ + sed -e 's/]*>//g' | \ + sed -e 's/<\/td>/;/g' | \ + sed -e 's/<[/\]\{0,1\}a[^>]*>//g' | \ + sed -e 's/<[/\]\{0,1\}nobr>//g' \ + > courses.txt + + + + + + diff --git a/automation-sys320/week13/courses.txt b/automation-sys320/week13/courses.txt new file mode 100644 index 0000000..b2bf5ce --- /dev/null +++ b/automation-sys320/week13/courses.txt @@ -0,0 +1,598 @@ +NumberCourse TitleCreditSeatsDaysTimesInstructorDatesPrerequisite(s)Location +ACC 135-01;Accounting for Decision Making;3;11;W;9AM-11:45AM;Nicole Morris; 1/16 - 5/03;None;GBTC 114; +ACC 145-01;Financial Accounting;3;12;TF;11:30AM-12:45PM;Charles Bush; 1/16 - 5/03;Take ACC-135 OR with... more;GBTC 114; +ACC 231-01;Intermediate Accounting II;3;16;W;12:15PM-3PM;Nicole Morris; 1/16 - 5/03;ACC-230;GBTC 114; +ACC 370-01SL;Volunteer Income Tax Assistanc;1;14;TBA;Cathy Duffy; 1/16 - 5/03;Complete ACC-325 or ... more; +ACC 390-81;Accounting Internship;2;20;TBA;Barrie Silver; 1/16 - 5/03;Complete ACC-231; +ACC 420-51;Auditing;3;17;TH;5:30PM-8:15PM;Joseph Paquin; 1/16 - 5/03;MTH-200 ?ACC-231 is ... more;JOYC 305; +ART 110-01;Drawing, Introductory;3;-1;W;12:15PM-3PM;Rebecca Schwarz; 1/16 - 5/03;None;SKFA 100; +ART 120-01;Art History;3;0;TF;8:30AM-9:45AM;Olivia Scarpa; 1/16 - 5/03;None; +ART 215-51;Photography, Intermediate;3;6;T;5:30PM-8:15PM;Jordan Douglas; 1/16 - 5/03;ART-115;JOYC 102; +ART 235-01;Introduction to Painting;3;5;W;9AM-11:45AM;Sage Tucker-Ketcham; 1/16 - 5/03;Take ART-110.;CCM 434; +ART 312-01;Printmaking Studio;3;5;T;4PM-8PM;Katie Loesel; 1/16 - 5/03;ART-110 or ART-135 ... more;CCM 434; +ART 339-51;Painting Other Worlds;3;6;TH;5:30PM-8:15PM;Mallory Breiner; 1/16 - 5/03;None;CCM 434; +ART 380-01;Adv. Art History:Spec. Topics;3;5;W;12:15PM-3PM;Stella Marrs; 1/16 - 5/03;TAKE ART-120.;MIC 305/306; +BRD 110-02;Video Storytelling;3;2;MTH;11:30AM-12:45PM;Keith Oppenheim; 1/16 - 5/03;None;GBTC 014; +BRD 117-01;Intro to Brd Wrtng;3;8;MTH;4PM-5:15PM;Keith Oppenheim; 1/16 - 5/03;None;GBTC 014; +BRD 130-01;Audio Production;3;5;TF;1PM-2:15PM;John Billingsley; 1/16 - 5/03;None;GBTC 014; +BRD 140-01;Radio Production I;3;0;TF;2:30PM-3:45PM;John Billingsley; 1/16 - 5/03;None;GBTC 014; +BRD 245-01;Video Field Production;3;4;M;1PM-3:45PM;Janet Weinstein; 1/16 - 5/03;Complete one of the ... more;GBTC 014; +BRD 380-01;Truth in the Era of Fake News;3;1;TH;1PM-3:45PM;David Wright; 1/16 - 5/03;Complete 60 credits ... more;MIC 305/306; +BUS 110-01;Biz Entrepreneurial Mindset;3;3;MTH;2:30PM-3:45PM;Marie Segares; 1/16 - 5/03;None;JOYC 102; +BUS 120-01;Marketing the Org. Mindset;3;5;TF;1PM-2:15PM;Marie Segares; 1/16 - 5/03;BUS-110 or permisiso... more;CCM 221; +BUS 120-02;Marketing the Org. Mindset;3;16;TF;4PM-5:15PM;Marie Segares; 1/16 - 5/03;BUS-110 or permisiso... more;GBTC 114; +BUS 120-04;Marketing the Org. Mindset;3;2;MTH;1PM-2:15PM;Joseph O'Grady; 1/16 - 5/03;BUS-110 or permisiso... more;GBTC 112; +BUS 310-01;Int'l Bus. Macroeconomics;3;1;TF;11:30AM-12:45PM;Parthiv Patel; 1/16 - 5/03;BUS-210,ECN-255;GBTC 217; +CCC 310-01;Integrative Film Practices;1;9;MTH;10AM-11:15AM;Kerry Noonan; 1/16 - 2/16;Film majors only. Ta... more;JOYC 304; +CCC 410-01;College Capstone: SSB;5;7;W;12:15PM-3PM;Parthiv Patel; 1/16 - 5/03;Must complete COR-31... more;GBTC 112; +CCC 410-51;College Capstone;5;6;TH;4PM-6:45PM;Tanya Stone; 1/16 - 5/03;Must complete COR-31... more;MIC 305/306; +CCC 410BRD-01;Broadcast Media Capstone;4;4;W;9AM-11:15AM;Keith Oppenheim; 1/16 - 5/03;Must complete COR-31... more;GBTC 014; +CCC 410COM-01SL;Communication Capstone;4;5;T;8:30AM-11:15AM;Nancy Kerr; 1/16 - 5/03;Must complete COR-31... more;CCM 212; +CCC 410CRE-01;Creative Media Capstone;4;2;MW;1PM-1:50PM,
12:15PM-3PM;Alan Larsen; 1/16 - 5/03;Must complete COR-31... more;SKFA 100; +CCC 410CRJ-71;College Capstone: Crim. Just.;3;5;T;1PM-2:15PM;Anthony Perriello; 1/16 - 5/03;Must complete COR-31... more;JOYC 202; +CCC 410EDU-01;CC: Student Teaching Capstone;3;9;T;4PM-6:45PM;Megan Jones; 1/16 - 5/03;Must complete COR-31... more;FREE 201; +CCC 410ENP-71;College Capstone;4;13;TH;11:30AM-2:15PM;Valerie Esposito; 1/16 - 5/03;Must complete COR-31... more;JOYC 313; +CCC 410FLM-01;College Capstone:Filmmaking;4;1;T;2:30PM-5:15PM;Julia Swift; 1/16 - 5/03;Must complete COR-31... more;CCM 305; +CCC 410FLM-02;College Capstone:Filmmaking;4;4;W;12:15PM-3PM;Julia Swift; 1/16 - 5/03;Must complete COR-31... more;CCM 305; +CCC 410ITS-01;Capstone Design;2;9;MTH;8:30AM-9:45AM;James Hoag; 1/16 - 5/03;Must complete COR-31... more;JOYC 201; +CCC 410LEG-71;College Capstone: Law;3;0;T;1PM-2:15PM;Anthony Perriello; 1/16 - 5/03;Must complete COR-31... more;JOYC 202; +CCC 410PSY-01;Psychology Capstone;3;9;W;9AM-11:45AM;Gary Baker; 1/16 - 5/03;Must complete COR-31... more;JOYC 313; +CCC 410SOI-01;College Capstone SoSI;3;2;W;9AM-11:45AM;Sianay Clifford; 1/16 - 5/03;Must complete COR-31... more;JOYC 311; +CCC 410SWK-01;Social Work Capstone;3;8;M;8:30AM-11:15AM;Annemarie Conlon; 1/16 - 5/03;Must complete COR-31... more;JOYC 212; +CCC 411FIN-01;College Capstone - Finance;3;20;TF;10AM-11:15AM;Frederick Burkhardt; 1/16 - 5/03;Complete FIN-300,COR... more;GBTC 217; +CCC 412-01;ITS Capstone Snr Project:CSIN;3;1;MTH;8:30AM-9:45AM;Wei Kian Chen; 1/16 - 5/03;Complete CCC-410ITS ... more;JOYC 211; +CCC 412-02;ITS Capstone Snr Project:DATA;3;1;MTH;8:30AM-9:45AM;Wei Kian Chen; 1/16 - 5/03;Complete CCC-410ITS ... more;JOYC 211; +CCC 412-03;ITS Capstone Snr Project:CNCS;3;-3;MTH;8:30AM-9:45AM;Joe Eastman; 1/16 - 5/03;Complete CCC-410ITS ... more;CCM 221; +CCC 412-04;ITS Capstone Snr Project:DIGF;3;10;MTH;8:30AM-9:45AM;Mariam Khader; 1/16 - 5/03;Complete CCC-410ITS ... more;GBTC 117; +CCC 412-05;ITS Capstone Snr Project:MATH;3;0;MTH;8:30AM-9:45AM;Wei Kian Chen; 1/16 - 5/03;Complete CCC-410ITS ... more;JOYC 211; +CCC 412DDL-71;DDL Capstone III;5;17;W;9AM-11:45AM;Michael Kelly; 1/16 - 5/03;Complete CCC-410ITS ... more;GBTC 206; +CCM 491-81;Comm Media Internship;1;18;TBA;Sarah Moore; 1/16 - 5/03;CCM Division student... more; +CCM 492-81;Comm Media Internship;2;18;TBA;Sarah Moore; 1/16 - 5/03;CCM Division student... more; +CCM 493-81;Comm Media Internship;3;6;TBA;Sarah Moore; 1/16 - 5/03;CCM Division student... more; +CCM 494-81;Comm Media Internship;4;17;TBA;Sarah Moore; 1/16 - 5/03;CCM Division student... more; +CCM 495-81;Comm Media Internship;5;18;TBA;Sarah Moore; 1/16 - 5/03;CCM Division student... more; +CCM 496-81;Comm Media Internship;6;18;TBA;Sarah Moore; 1/16 - 5/03;CCM Division student... more; +CCX 105-01;Academic Reset;0;14;T;1PM-2:30PM;Elaine O'Reilly; 1/30 - 3/22;None;MIC 301; +CCX 105-02;Academic Reset;0;14;W;11AM-12:30PM;Elaine O'Reilly; 1/30 - 3/22;None;MIC 301; +CMP 101-01;Champ 101;0;11;MTH;10AM-11:15AM;Melanie Brown; 1/15 - 3/29;None;FREE 201; +CMP 101-02;Champ 101;0;13;MTH;11:30AM-12:45PM;Elaine O'Reilly; 1/15 - 3/29;None;FREE 201; +COM 100-01;Human Communication, Foundat.;3;3;TF;2:30PM-3:45PM;Cheryl Casey; 1/16 - 5/03;You may not enroll i... more;CCM 442; +COM 100-02;Human Communication, Foundat.;3;8;TF;11:30AM-12:45PM;Cheryl Casey; 1/16 - 5/03;You may not enroll i... more;CCM 444; +COM 110-02;Public Speaking;3;1;MTH;1PM-2:15PM;Nancy Kerr; 1/16 - 5/03;None;CCM 424; +COM 210-01;Principles of Public Relations;3;4;MTH;10AM-11:15AM;Nancy Kerr; 1/16 - 5/03;Complete either COM-... more;CCM 424; +COM 270-51;Intercultural Communication;3;6;W;5:30PM-8:15PM;Nadia DuBose; 1/16 - 5/03;Must have completed ... more;CCM 424; +COM 325-51;Social Media Influencer;3;1;W;5:30PM-8:15PM;Lindsay Bumps; 1/16 - 5/03;(MKT 250 - Digital M... more;JOYC 203; +COM 355-01;Prof. Communication Practices;1;10;TH;2:30PM-3:20PM;Sarah Moore; 1/16 - 5/03;Minimum 60 credits a... more;CCM 424; +COM 365-01;Legal Issues in Communication;3;10;MTH;4PM-5:15PM;Barrie Silver; 1/16 - 5/03;Must complete 60 cre... more;JOYC 202; +COR 103-01;Navigating Information;3;-1;MTH;8:30AM-9:45AM;Charles Bashaw; 1/16 - 5/03;Take COR-104 concurr... more;JOYC 305; +COR 103-02;Navigating Information;3;0;MTH;10AM-11:15AM;Charles Bashaw; 1/16 - 5/03;Take COR-104 concurr... more;JOYC 305; +COR 103-03;Navigating Information;3;1;MTH;8:30AM-9:45AM;Marianne Bhonslay; 1/16 - 5/03;Take COR-104 concurr... more;JOYC 202; +COR 103-04;Navigating Information;3;1;MTH;10AM-11:15AM;Marianne Bhonslay; 1/16 - 5/03;Take COR-104 concurr... more;JOYC 202; +COR 103-05;Navigating Information;3;0;W;12:15PM-3PM;Marianne Bhonslay; 1/16 - 5/03;Take COR-104 concurr... more;JOYC 203; +COR 103-06;Navigating Information;3;-1;TF;10AM-11:15AM;Clinton Bryant; 1/16 - 5/03;Take COR-104 concurr... more;JOYC 202; +COR 103-07;Navigating Information;3;0;TF;11:30AM-12:45PM;Clinton Bryant; 1/16 - 5/03;Take COR-104 concurr... more;JOYC 202; +COR 103-08;Navigating Information;3;0;TF;2:30PM-3:45PM;Clinton Bryant; 1/16 - 5/03;Take COR-104 concurr... more;JOYC 202; +COR 103-09;Navigating Information;3;0;MTH;2:30PM-3:45PM;Cheryl Casey; 1/16 - 5/03;Take COR-104 concurr... more;JOYC 311; +COR 103-10;Navigating Information;3;0;MTH;4PM-5:15PM;Cheryl Casey; 1/16 - 5/03;Take COR-104 concurr... more;JOYC 313; +COR 103-11;Navigating Information;3;0;TF;10AM-11:15AM;Jeffrey Haig; 1/16 - 5/03;Take COR-104 concurr... more;WICK 102; +COR 103-12;Navigating Information;3;-1;TF;11:30AM-12:45PM;Jeffrey Haig; 1/16 - 5/03;Take COR-104 concurr... more;WICK 102; +COR 103-13;Navigating Information;3;0;TF;11:30AM-12:45PM;Amanda Young; 1/16 - 5/03;Take COR-104 concurr... more;WICK 101; +COR 103-14;Navigating Information;3;0;TF;1PM-2:15PM;Erik Kaarla; 1/16 - 5/03;Take COR-104 concurr... more;WICK 101; +COR 103-15;Navigating Information;3;0;TF;11:30AM-12:45PM;Erik Kaarla; 1/16 - 5/03;Take COR-104 concurr... more;JOYC 302; +COR 103-17;Navigating Information;3;0;TF;4PM-5:15PM;Erik Kaarla; 1/16 - 5/03;Take COR-104 concurr... more;JOYC 302; +COR 103-18;Navigating Information;3;0;TF;1PM-2:15PM;Abijah Manga; 1/16 - 5/03;Take COR-104 concurr... more;WICK 102; +COR 103-19;Navigating Information;3;0;TF;2:30PM-3:45PM;Abijah Manga; 1/16 - 5/03;Take COR-104 concurr... more;WICK 102; +COR 103-21;Navigating Information;3;7;TH;8:30AM-11:15AM;Kelly Thomas; 1/16 - 5/03;Take COR-104 concurr... more;JOYC 313; +COR 103-22;Navigating Information;3;-1;TF;10AM-11:15AM;Rachel Moser-Hardy; 1/16 - 5/03;Take COR-104 concurr... more;JOYC 313; +COR 103-23;Navigating Information;3;0;MTH;4PM-5:15PM;Kristin Novotny; 1/16 - 5/03;Take COR-104 concurr... more;GBTC 217; +COR 103-24;Navigating Information;3;0;TF;1PM-2:15PM;David Rous; 1/16 - 5/03;Take COR-104 concurr... more;MIC 305/306; +COR 103-25;Navigating Information;3;0;TF;2:30PM-3:45PM;David Rous; 1/16 - 5/03;Take COR-104 concurr... more;MIC 305/306; +COR 103-26;Navigating Information;3;0;W;12:15PM-3PM;William Stratton; 1/16 - 5/03;Take COR-104 concurr... more;CCM 424; +COR 103-27;Navigating Information;3;0;T;10AM-12:45PM;Kelly Thomas; 1/16 - 5/03;Take COR-104 concurr... more;JOYC 304; +COR 103-28;Navigating Information;3;6;W;9AM-11:45AM;Kelly Thomas; 1/16 - 5/03;Take COR-104 concurr... more;JOYC 203; +COR 103-30;Navigating Information;3;1;TH;11:30AM-2:15PM;Kelly Thomas; 1/16 - 5/03;Take COR-104 concurr... more;CCM 442; +COR 103-51;Navigating Information;3;2;M;5:30PM-8:15PM;William Stratton; 1/16 - 5/03;Take COR-104 concurr... more;CCM 233; +COR 104-01;FYI: Making/Doing;3;0;TH;11:30AM-2:15PM;Jonathan Banfill; 1/16 - 5/03;Take Cor-103 concurr... more;GBTC 206; +COR 104-02;FYI: Making/Doing;3;-1;F;2:30PM-5:15PM;Jonathan Banfill; 1/16 - 5/03;Take Cor-103 concurr... more;GBTC 206; +COR 104-03;FYI: Making/Doing;3;1;MTH;1PM-2:15PM;Kelly Bowen; 1/16 - 5/03;Take Cor-103 concurr... more;GBTC 114; +COR 104-04;FYI: Making/Doing;3;0;MTH;2:30PM-3:45PM;Kelly Bowen; 1/16 - 5/03;Take Cor-103 concurr... more;GBTC 114; +COR 104-05;FYI: Making/Doing;3;1;MTH;11:30AM-12:45PM;Alfonso Capone; 1/16 - 5/03;Take Cor-103 concurr... more;FOST 100; +COR 104-06;FYI: Making/Doing;3;5;MTH;1PM-2:15PM;Alfonso Capone; 1/16 - 5/03;Take Cor-103 concurr... more;FOST 100; +COR 104-07;FYI: Making/Doing;3;2;TTH;5:30PM-6:45PM;Blake Randell; 1/16 - 5/03;Take Cor-103 concurr... more;JOYC 302; +COR 104-08;FYI: Making/Doing;3;5;TTH;5:30PM-6:45PM;Isabella Jeso; 1/16 - 5/03;Take Cor-103 concurr... more;WICK 100; +COR 104-09;FYI: Making/Doing;3;3;MTH;4PM-5:15PM;Isabella Jeso; 1/16 - 5/03;Take Cor-103 concurr... more;WICK 100; +COR 104-10;FYI: Making/Doing;3;5;TF;4PM-5:15PM;Isabella Jeso; 1/16 - 5/03;Take Cor-103 concurr... more;WICK 100; +COR 104-11;FYI: Making/Doing;3;0;MTH;10AM-11:15AM;David Kite; 1/16 - 5/03;Take Cor-103 concurr... more;JOYC 311; +COR 104-12;FYI: Making/Doing;3;0;MTH;11:30AM-12:45PM;David Kite; 1/16 - 5/03;Take Cor-103 concurr... more;WICK 102; +COR 104-13;FYI: Making/Doing;3;0;T;4PM-6:45PM;Rachel Moser-Hardy; 1/16 - 5/03;Take Cor-103 concurr... more;JOYC 311; +COR 104-14;FYI: Making/Doing;3;-1;F;2:30PM-5:15PM;Rachel Moser-Hardy; 1/16 - 5/03;Take Cor-103 concurr... more;CCM 233; +COR 104-15;FYI: Making/Doing;3;1;W;9AM-11:45AM;Erik Shonstrom; 1/16 - 5/03;Take Cor-103 concurr... more;CCM 444; +COR 104-16;FYI: Making/Doing;3;1;W;12:15PM-3PM;Erik Shonstrom; 1/16 - 5/03;Take Cor-103 concurr... more;CCM 444; +COR 104-17;FYI: Making/Doing;3;-1;TH;10AM-12:45PM;Erik Shonstrom; 1/16 - 5/03;Take Cor-103 concurr... more;JOYC 212; +COR 104-18;FYI: Making/Doing;3;-1;F;10AM-12:45PM;Erik Shonstrom; 1/16 - 5/03;Take Cor-103 concurr... more;GBTC 206; +COR 104-19;FYI: Making/Doing;3;0;MTH;11:30AM-12:45PM;Stephen Wehmeyer; 1/16 - 5/03;Take Cor-103 concurr... more;JOYC 311; +COR 104-20;FYI: Making/Doing;3;-1;MTH;1PM-2:15PM;Stephen Wehmeyer; 1/16 - 5/03;Take Cor-103 concurr... more;JOYC 202; +COR 104-21;FYI: Making/Doing;3;0;MTH;8:30AM-9:45AM;Ines De Haro; 1/16 - 5/03;Take Cor-103 concurr... more;WICK 101; +COR 104-22;FYI: Making/Doing;3;0;MTH;11:30AM-12:45PM;Ines De Haro; 1/16 - 5/03;Take Cor-103 concurr... more;WICK 101; +COR 104-23;FYI: Making/Doing;3;1;MTH;2:30PM-3:45PM;Amanda Young; 1/16 - 5/03;Take Cor-103 concurr... more;JOYC 313; +COR 104-24;FYI: Making/Doing;3;-1;W;9AM-11:45AM;Katheryn Wright; 1/16 - 5/03;Take Cor-103 concurr... more;JOYC 205; +COR 104-25;FYI: Making/Doing;3;-1;MTH;11:30AM-12:45PM;Zachary LaMalfa; 1/16 - 5/03;Take Cor-103 concurr... more;JOYC 302; +COR 104-27;FYI: Making/Doing;3;1;TF;11:30AM-12:45PM;Zachary LaMalfa; 1/16 - 5/03;Take Cor-103 concurr... more;GBTC 112; +COR 104-28;FYI: ____ (instructor Topic);3;3;W;9AM-11:45AM;Gordon Glover; 1/16 - 5/03;Take Cor-103 concurr... more;JOYC 302; +COR 104-51;FYI: Making/Doing;3;0;MW;5:30PM-6:45PM;Erik Shonstrom; 1/16 - 5/03;Take Cor-103 concurr... more;JOYC 212; +COR 201-51;Science Meaning Making;3;6;W;5:30PM-8:15PM;Velpula Paul; 1/16 - 5/03;Take COR-101, COR-10... more;WICK 102; +COR 202-01;Interdisciplinary Perspectives;3;-2;W;12:15PM-3PM;Joanna Caroline Toy; 1/16 - 5/03;Take COR-101, COR-10... more;JOYC 102; +COR 203-01;Culture Meaning Making;3;-2;TF;8:30AM-9:45AM;Charles Bashaw; 1/16 - 5/03;Take COR-101, COR-10... more;GBTC 112; +COR 203-02;Culture Meaning Making;3;-2;TF;10AM-11:15AM;Charles Bashaw; 1/16 - 5/03;Take COR-101, COR-10... more;GBTC 112; +COR 203-03;Culture Meaning Making;3;0;TF;10AM-11:15AM;Flavio Rizzo; 1/16 - 5/03;Take COR-101, COR-10... more;CCM 442; +COR 203-04;Culture Meaning Making;3;0;W;9AM-11:45AM;Veruska Cantelli; 1/16 - 5/03;Take COR-101, COR-10... more;JOYC 202; +COR 203-05;Culture Meaning Making;3;-2;W;12:15PM-3PM;Veruska Cantelli; 1/16 - 5/03;Take COR-101, COR-10... more;JOYC 202; +COR 203-06;Culture Meaning Making;3;-2;MTH;11:30AM-12:45PM;Gary Scudder; 1/16 - 5/03;Take COR-101, COR-10... more;JOYC 305; +COR 203-07;Culture Meaning Making;3;0;MTH;1PM-2:15PM;Ciaran Buckley; 1/16 - 5/03;Take COR-101, COR-10... more;WICK 102; +COR 203-08;Culture Meaning Making;3;0;TF;2:30PM-3:45PM;Michael Lange; 1/16 - 5/03;Take COR-101, COR-10... more;JOYC 304; +COR 203-09;Culture Meaning Making;3;-1;MTH;2:30PM-3:45PM;Ines De Haro; 1/16 - 5/03;Take COR-101, COR-10... more;WICK 102; +COR 203-10;Culture Meaning Making;3;-2;W;9AM-11:45AM;Faith Yacubian; 1/16 - 5/03;Take COR-101, COR-10... more;CCM 424; +COR 203-11;Culture Meaning Making;3;0;MTH;8:30AM-9:45AM;Alena Lange; 1/16 - 5/03;Take COR-101, COR-10... more;WICK 100; +COR 203-12;Culture Meaning Making;3;-2;MTH;10AM-11:15AM;Alena Lange; 1/16 - 5/03;Take COR-101, COR-10... more;WICK 100; +COR 203-13;Culture Meaning Making;3;0;MTH;11:30AM-12:45PM;Alena Lange; 1/16 - 5/03;Take COR-101, COR-10... more;WICK 100; +COR 203-14;Culture Meaning Making;3;-1;MTH;1PM-2:15PM;Rowshan Nemazee; 1/16 - 5/03;Take COR-101, COR-10... more;GBTC 217; +COR 203-15;Culture Meaning Making;3;0;MTH;2:30PM-3:45PM;Rowshan Nemazee; 1/16 - 5/03;Take COR-101, COR-10... more;GBTC 217; +COR 203-16;Culture Meaning Making;3;0;M;8:30AM-11:15AM;Flavio Rizzo; 1/16 - 5/03;Take COR-101, COR-10... more;MIC 305/306; +COR 203-17;Culture Meaning Making;3;0;M;11:30AM-2:15PM;Flavio Rizzo; 1/16 - 5/03;Take COR-101, COR-10... more;JOYC 313; +COR 203-18;Culture Meaning Making;3;-2;MTH;4PM-5:15PM;Stephen Wehmeyer; 1/16 - 5/03;Take COR-101, COR-10... more;JOYC 311; +COR 203-19;Culture Meaning Making;3;-2;TF;11:30AM-12:45PM;Stephen Wehmeyer; 1/16 - 5/03;Take COR-101, COR-10... more;CCM 424; +COR 203-20;Culture Meaning Making;3;0;TF;10AM-11:15AM;Stephen Wehmeyer; 1/16 - 5/03;Take COR-101, COR-10... more;CCM 444; +COR 204-01;Theoretical Perspectives;3;-2;MTH;1PM-2:15PM;Ariel Burgess; 1/16 - 5/03;Take COR-101, COR-10... more;JOYC 304; +COR 204-02;Theoretical Perspectives;3;-2;MTH;2:30PM-3:45PM;Ariel Burgess; 1/16 - 5/03;Take COR-101, COR-10... more;JOYC 304; +COR 204-03;Theoretical Perspectives;3;-2;MTH;4PM-5:15PM;Ariel Burgess; 1/16 - 5/03;Take COR-101, COR-10... more;JOYC 304; +COR 204-04;Theoretical Perspectives;3;-2;TF;11:30AM-12:45PM;Alfonso Capone; 1/16 - 5/03;Take COR-101, COR-10... more;WICK 100; +COR 204-05;Theoretical Perspectives;3;-1;TF;1PM-2:15PM;Alfonso Capone; 1/16 - 5/03;Take COR-101, COR-10... more;WICK 100; +COR 204-06;Theoretical Perspectives;3;-2;MTH;1PM-2:15PM;Weiling Deng; 1/16 - 5/03;Take COR-101, COR-10... more;JOYC 212; +COR 204-07;Theoretical Perspectives;3;-2;MTH;2:30PM-3:45PM;Weiling Deng; 1/16 - 5/03;Take COR-101, COR-10... more;JOYC 212; +COR 204-08;Theoretical Perspectives;3;-2;MTH;2:30PM-3:45PM;David Kite; 1/16 - 5/03;Take COR-101, COR-10... more;JOYC 302; +COR 204-09;Theoretical Perspectives;3;-2;W;9AM-11:45AM;Gary Scudder; 1/16 - 5/03;Take COR-101, COR-10... more;JOYC 301; +COR 204-10;Theoretical Perspectives;3;-1;TF;8:30AM-9:45AM;Michael Lange; 1/16 - 5/03;Take COR-101, COR-10... more;CCM 233; +COR 204-11;Theoretical Perspectives;3;-2;TF;10AM-11:15AM;Michael Lange; 1/16 - 5/03;Take COR-101, COR-10... more;CCM 233; +COR 204-12;Theoretical Perspectives;3;-2;TF;1PM-2:15PM;Michael Lange; 1/16 - 5/03;Take COR-101, COR-10... more;JOYC 304; +COR 204-13;Theoretical Perspectives;3;-3;MTH;11:30AM-12:45PM;Kerry Noonan; 1/16 - 5/03;Take COR-101, COR-10... more;JOYC 304; +COR 204-14;Theoretical Perspectives;3;-2;MTH;2:30PM-3:45PM;Kerry Noonan; 1/16 - 5/03;Take COR-101, COR-10... more;FOST 100; +COR 204-15;Theoretical Perspectives;3;-2;M;4PM-6:45PM;Gary Scudder; 1/16 - 5/03;Take COR-101, COR-10... more;WICK 101; +COR 204-16;Theoretical Perspectives;3;2;TH;4PM-6:45PM;Gary Scudder; 1/16 - 5/03;Take COR-101, COR-10... more;GBTC 114; +COR 204-17;Theoretical Perspectives;3;-3;TF;8:30AM-9:45AM;Kristin Wolf; 1/16 - 5/03;Take COR-101, COR-10... more;JOYC 302; +COR 204-18;Theoretical Perspectives;3;-3;TF;10AM-11:15AM;Kristin Wolf; 1/16 - 5/03;Take COR-101, COR-10... more;JOYC 302; +COR 204-19;Theoretical Perspectives;3;-3;TF;11:30AM-12:45PM;Kristin Wolf; 1/16 - 5/03;Take COR-101, COR-10... more;JOYC 311; +COR 303-01;PastPresent;3;1;MTH;8:30AM-9:45AM;Ciaran Buckley; 1/16 - 5/03;Take COR-101, COR-10... more;JOYC 102; +COR 303-02;PastPresent;3;0;MTH;10AM-11:15AM;Ciaran Buckley; 1/16 - 5/03;Take COR-101, COR-10... more;JOYC 102; +COR 303-03;PastPresent;3;-1;MTH;1PM-2:15PM;Edward Cafferty; 1/16 - 5/03;Take COR-101, COR-10... more;WICK 100; +COR 303-04;PastPresent;3;0;TF;1PM-2:15PM;Edward Cafferty; 1/16 - 5/03;Take COR-101, COR-10... more;FOST 100; +COR 303-05;PastPresent;3;-1;TF;4PM-5:15PM;Edward Cafferty; 1/16 - 5/03;Take COR-101, COR-10... more;FOST 100; +COR 303-07;PastPresent;3;2;M;11:30AM-2:15PM;Veruska Cantelli; 1/16 - 5/03;Take COR-101, COR-10... more;GBTC 206; +COR 303-08;PastPresent;3;0;TF;4PM-5:15PM;Ciaran Buckley; 1/16 - 5/03;Take COR-101, COR-10... more;CCM 444; +COR 303-09;PastPresent;3;0;W;12:15PM-3PM;Fred Kosnitsky; 1/16 - 5/03;Take COR-101, COR-10... more;JOYC 311; +COR 303-10;PastPresent;3;0;TF;1PM-2:15PM;Rowshan Nemazee; 1/16 - 5/03;Take COR-101, COR-10... more;CCM 424; +COR 303-11;PastPresent;3;1;TF;2:30PM-3:45PM;Rowshan Nemazee; 1/16 - 5/03;Take COR-101, COR-10... more;CCM 424; +COR 303-13;PastPresent;3;1;W;12:15PM-3PM;Flavio Rizzo; 1/16 - 5/03;Take COR-101, COR-10... more;WICK 101; +COR 303-14;PastPresent;3;6;MTH;8:30AM-9:45AM;Veruska Cantelli; 1/16 - 5/03;Take COR-101, COR-10... more;FOST 100; +COR 303-15;PastPresent;3;0;MTH;10AM-11:15AM;Gary Scudder; 1/16 - 5/03;Take COR-101, COR-10... more;JOYC 301; +COR 303-205;Northern Ireland;3;0;T;2:45PM-5:30PM;Liz Gillis; 1/16 - 5/03;Take COR-101, COR-10... more; +COR 304-01;Digital Methods;3;0;T;2:30PM-5:15PM;Jonathan Banfill; 1/16 - 5/03;Take COR-101, COR-10... more;GBTC 112; +COR 304-02;Digital Methods;3;0;W;12:15PM-3PM;Jonathan Banfill; 1/16 - 5/03;Take COR-101, COR-10... more;JOYC 305; +COR 304-03;Digital Methods;3;0;M;2:30PM-5:15PM;Kristian Brevik; 1/16 - 5/03;Take COR-101, COR-10... more;CCM 442; +COR 304-04;Digital Methods;3;0;TH;2:30PM-5:15PM;Kristian Brevik; 1/16 - 5/03;Take COR-101, COR-10... more;CCM 442; +COR 304-05;Digital Methods;3;-1;T;10AM-12:45PM;Weiling Deng; 1/16 - 5/03;Take COR-101, COR-10... more;JOYC 102; +COR 304-06;Digital Methods;3;-1;T;2:30PM-5:15PM;Weiling Deng; 1/16 - 5/03;Take COR-101, COR-10... more;JOYC 102; +COR 304-07;Digital Methods;3;1;T;4PM-6:45PM;Joyce-Zoe Farley; 1/16 - 5/03;Take COR-101, COR-10... more;JOYC 313; +COR 304-08;Digital Methods;3;0;TH;4PM-6:45PM;Joyce-Zoe Farley; 1/16 - 5/03;Take COR-101, COR-10... more;WICK 102; +COR 304-10;Digital Methods;3;2;M;4PM-6:45PM;Amy Howe; 1/16 - 5/03;Take COR-101, COR-10... more;WICK 102; +COR 304-103;Graffiti and Unsanctioned Art;3;5;M;1PM-3:45PM;Melissa Proietti; 1/15 - 5/03;Take COR-101, COR-10... more; +COR 304-11;Digital Methods;3;1;W;9AM-11:45AM;Amy Howe; 1/16 - 5/03;Take COR-101, COR-10... more;WICK 100; +COR 304-12;Digital Methods;3;3;W;12:15PM-3PM;Amy Howe; 1/16 - 5/03;Take COR-101, COR-10... more;WICK 100; +COR 304-13;Digital Methods;3;1;T;8:30AM-11:15AM;Robert Mayer; 1/16 - 5/03;Take COR-101, COR-10... more;WICK 101; +COR 304-15;Digital Methods;3;0;TF;1PM-2:15PM;Kimberly McCray-Woodruff; 1/16 - 5/03;Take COR-101, COR-10... more;JOYC 311; +COR 304-202;Podcasting in Dublin;3;3;W;9AM-11:45AM;Marisa Brown; 1/16 - 5/03;Take COR-101, COR-10... more; +COR 304-204;Writing the City: Dublin;3;3;T;2:45PM-5:30PM;Nicole Rourke; 1/16 - 5/03;Take COR-101, COR-10... more; +CRE 100-01;Making Art;3;-1;TF;10AM-12:45PM,
10AM-12PM;Gordon Glover; 1/16 - 5/03;Must be enrolled in ... more;CCM 434; +CRE 180-01;Making Culture;3;10;MTH;11:30AM-12:45PM;Peter Gallo; 1/16 - 5/03;Take 0 credits; Crea... more;JOYC 301; +CRE 180-02;Making Culture;3;0;MTH;1PM-2:15PM;Peter Gallo; 1/16 - 5/03;Take 0 credits; Crea... more;JOYC 102; +CRE 240-01;Creative Media Prof Pract I;1;-4;T;4PM-4:50PM;Micah Wood; 1/16 - 5/03;Complete 30 credits.... more;SKFA 100; +CRE 250-01;Creative Media Projects I;3;-5;MTH;10AM-12:45PM,
10AM-12PM;Gordon Glover; 1/16 - 5/03;COMPLETE CRE-200.;CCM 434; +CRE 250-02;Creative Media Projects I;3;5;MTH;2:30PM-5:15PM,
2:30PM-4:30PM;Micah Wood; 1/16 - 5/03;COMPLETE CRE-200.;CCM 434; +CRE 350-01;Creative Media Portfolio 2;3;9;MTH;10AM-12PM,
10AM-12:45PM;Alan Larsen; 1/16 - 5/03;Complete CRE-250, CR... more;CCM 434; +CRJ 121-01;Criminal Procedure;3;8;TH;2:30PM-5:15PM;Eric Friedman; 1/16 - 5/03;None;CCM 221; +CRJ 121-51;Criminal Procedure;3;2;M;5:30PM-8:15PM;Sally Adams; 1/16 - 5/03;None;GBTC 217; +CRJ 235-51;Juvenile Justice;3;7;TH;5:30PM-8:15PM;Pamela Marsh; 1/16 - 5/03;None;JOYC 301; +CRJ 265-01;Victimology;3;-2;MTH;11:30AM-12:45PM;Annemarie Conlon; 1/16 - 5/03;None;JOYC 205; +CRJ 450-01;Criminal Justice Reform;3;6;T;10AM-12:45PM;Anthony Perriello; 1/16 - 5/03;Take 60 credits;JOYC 305; +CRJ 490-81;Criminal Justice Field Exp;6;23;TBA;Stephen Miller; 1/16 - 5/03;Must complete 90 cre... more; +CSI 140-02;Introduction to Programming;3;1;MTH;11:30AM-12:45PM;Vikas Thammanna Gowda; 1/16 - 5/03;None;JOYC 211; +CSI 140-04;Introduction to Programming;3;5;MTH;1PM-2:15PM;Sarah Pettitt; 1/16 - 5/03;None;JOYC 211; +CSI 160-02;Python Programming;3;0;TF;1PM-2:15PM;Sarah Pettitt; 1/16 - 5/03;None;MIC 308; +CSI 160-03;Python Programming;3;0;TF;8:30AM-9:45AM;Sarah Pettitt; 1/16 - 5/03;None;JOYC 211; +CSI 180-01;Innov I: Technology Sandbox;3;3;TF;10AM-11:15AM;Brian Hall; 1/16 - 5/03;Complete: CSI-120 OR... more;JOYC 210; +CSI 180-02;Innov I: Technology Sandbox;3;0;TF;11:30AM-12:45PM;Brian Hall; 1/16 - 5/03;Complete: CSI-120 OR... more;JOYC 210; +CSI 240-01;Advanced Programming;3;3;MTH;10AM-11:15AM;Murat Gungor; 1/16 - 5/03;Complete CSI-140 wit... more;MIC 308; +CSI 240-02;Advanced Programming;3;1;MTH;11:30AM-12:45PM;Murat Gungor; 1/16 - 5/03;Complete CSI-140 wit... more;MIC 308; +CSI 240-03;Advanced Programming;3;4;TF;2:30PM-3:45PM;Alexandre Tolstenko Nogueira; 1/16 - 5/03;Complete CSI-140 wit... more;JOYC 211; +CSI 240-04;Advanced Programming;3;0;TF;1PM-2:15PM;Wei Kian Chen; 1/16 - 5/03;Complete CSI-140 wit... more;JOYC 201; +CSI 260-01;Advanced Python;3;-2;MTH;2:30PM-3:45PM;Sarah Pettitt; 1/16 - 5/03;Complete CSI-160;JOYC 211; +CSI 275-01;Network Programming;3;-4;MTH;11:30AM-12:45PM;Scott Barrett; 1/16 - 5/03;Complete CSI-240 or ... more;JOYC 201; +CSI 275-02;Network Programming;3;-5;MTH;1PM-2:15PM;Scott Barrett; 1/16 - 5/03;Complete CSI-240 or ... more;JOYC 201; +CSI 280-51;Innov II:Open Source Soft Dev;3;-2;W;5:30PM-8:15PM;Christopher Bendel; 1/16 - 5/03;Grade C or better in... more;CCM 233; +CSI 280-52;Innov II:Open Source Soft Dev;3;-1;T;5:30PM-8:15PM;Christopher Bendel; 1/16 - 5/03;Grade C or better in... more;JOYC 205; +CSI 281-01;Data Structures Algorithms;3;11;TF;1PM-2:15PM;Alexandre Tolstenko Nogueira; 1/16 - 5/03;CSI-240 with minimum... more;JOYC 211; +CSI 300-01;Database Management Systems;3;-5;MTH;2:30PM-3:45PM;Frank Canovatchel; 1/16 - 5/03;Complete CSI-270 OR ... more;JOYC 201; +CSI 300-02;Database Management Systems;3;-4;MTH;4PM-5:15PM;Frank Canovatchel; 1/16 - 5/03;Complete CSI-270 OR ... more;JOYC 201; +CSI 318-51;iOS Development;3;7;MW;5:30PM-6:45PM;Morgan Seielstad; 1/16 - 5/03;Complete CSI-240 or ... more;JOYC 210; +CSI 357-01;Server-Side Application Dev.;3;5;TF;8:30AM-9:45AM;Frank Canovatchel; 1/16 - 5/03;Complete CSI-120 and... more;JOYC 201; +CSI 420-01;Software Refactoring;3;-2;T;10AM-12:45PM;Murat Gungor; 1/16 - 5/03;Complete CSI-270 or ... more;MIC 308; +DAT 210-01;Introduction to Data Analytics;3;9;TF;2:30PM-3:45PM;Vikas Thammanna Gowda; 1/16 - 5/03;Complete MTH-180 and... more;JOYC 210; +DAT 410-01;Machine Learning;3;8;TF;4PM-5:15PM;Vikas Thammanna Gowda; 1/16 - 5/03;Complete CSI-270 or ... more;JOYC 210; +DAT 430-01;Data Visualization;3;12;MTH;10AM-11:15AM;Vikas Thammanna Gowda; 1/16 - 5/03;Complete DAT-210;JOYC 210; +DDL 190-01;Project Design I;3;-3;W;9AM-11:45AM;Cynthia Brandenburg; 1/16 - 5/03;None;CCM 442; +DDL 290-01;Project Design II;3;5;W;9AM-11:45AM;Cynthia Brandenburg; 1/16 - 5/03;Take DDL-180 and DDL... more;CCM 442; +DDL 350-51;Degree Design Lab Practicum;3;14;W;5:30PM-8:15PM;Michael Kelly; 1/16 - 5/03;Take DDL-186.;JOYC 304; +DDL 401-71;Competency: Analysis;1;13;M;10AM-11:15AM;Michael Kelly; 1/16 - 2/16;None;WICK 102; +DDL 401-72;Competency: Analysis;1;13;M;8:30AM-9:45AM;Michael Kelly; 4/01 - 5/03;None;WICK 102; +DDL 402-71;Competency: Collaboration;1;14;TH;8:30AM-9:45AM;Michael Kelly; 1/16 - 2/16;None;WICK 102; +DDL 402-72;Competency: Collaboration;1;13;TH;10AM-11:15AM;Michael Kelly; 4/01 - 5/03;None;WICK 102; +DDL 403-71;Competency: Communication;1;12;TH;8:30AM-9:45AM;Michael Kelly; 2/19 - 3/29;None;WICK 102; +DDL 404-71;Competency: Creativity;1;11;TH;10AM-11:15AM;Michael Kelly; 2/19 - 3/29;None;WICK 102; +DDL 405-71;Competency: Diversityinclusn;1;13;M;10AM-11:15AM;Michael Kelly; 2/19 - 3/29;None;WICK 102; +DDL 406-71;Competency: Globalcultrl;1;11;M;10AM-11:15AM;Michael Kelly; 2/19 - 3/29;None;WICK 102; +DDL 407-71;Competency: Info Literacy;1;14;M;8:30AM-9:45AM;Michael Kelly; 2/19 - 3/29;None;WICK 102; +DDL 408-71;Competency: Inquiry;1;10;M;8:30AM-9:45AM;Michael Kelly; 2/19 - 3/29;None;WICK 102; +DDL 409-71;Competency: Integration;1;14;M;10AM-11:15AM;Michael Kelly; 1/16 - 2/16;None;WICK 102; +DDL 409-72;Competency: Integration;1;14;M;8:30AM-9:45AM;Michael Kelly; 4/01 - 5/03;None;WICK 102; +DDL 410-71;Competency: Quant Literacy;1;15;M;8:30AM-9:45AM;Michael Kelly; 1/16 - 2/16;None;WICK 102; +DDL 410-72;Competency: Quant Literacy;1;13;M;10AM-11:15AM;Michael Kelly; 4/01 - 5/03;None;WICK 102; +DDL 411-71;Competency: Sci Literacy;1;14;M;8:30AM-9:45AM;Michael Kelly; 1/16 - 2/16;None;WICK 102; +DDL 411-72;Competency: Sci Literacy;1;12;M;10AM-11:15AM;Michael Kelly; 4/01 - 5/03;None;WICK 102; +DDL 412-71;Competency: Tech Literacy;1;13;TH;10AM-11:15AM;Michael Kelly; 1/16 - 2/16;None;WICK 102; +DDL 412-72;Competency: Tech Literacy;1;13;TH;8:30AM-9:45AM;Michael Kelly; 4/01 - 5/03;None;WICK 102; +ECN 255-01;Managerial Economics;3;7;TF;1PM-2:15PM;Jennifer Vincent; 1/16 - 5/03;Take 30 credits;JOYC 305; +ECN 255-02;Managerial Economics;3;7;TF;2:30PM-3:45PM;Jennifer Vincent; 1/16 - 5/03;Take 30 credits;JOYC 305; +ECN 350-01;Financial Economic Modeling;3;8;MTH;1PM-2:15PM;Frederick Burkhardt; 1/16 - 5/03;Complete MTH-180, FI... more;JOYC 311; +EDU 112-01;Integrating Technology;3;9;T;1PM-3:45PM;Megan Jones; 1/16 - 5/03;None;FREE 201; +EDU 160-51;Math Science for Yng. Chldn;3;11;W;5:30PM-8:15PM;Erica DiVece; 1/16 - 5/03;None;FREE 201; +EDU 233-51;Teaching Diverse Learners;3;10;TH;5:30PM-8:15PM;Kara Griswold; 1/16 - 5/03;Complete EDU-110;FREE 201; +EDU 399-81;Trauma Informed Classrooms;3;0;TBA;John Stroup; 1/16 - 5/03;None; +EDU 490-01;Integrated Curr Student Teac;9;18;TBA;John Stroup; 1/16 - 5/03;EDU-312 and EDU-313 ... more; +EDU 490-02;Integrated Curr Student Teac;9;19;TBA;Megan Jones; 1/16 - 5/03;EDU-312 and EDU-313 ... more; +EGD 220-01AA;Game Studio I;3;0;MTH;8:30AM-9:45AM;Peter Wehr; 1/16 - 5/03;All - GDES, GMRT, GP... more;CCM 222; +EGD 220-01GD;Game Studio I;3;0;MTH;8:30AM-9:45AM;Peter Wehr; 1/16 - 5/03;All - GDES, GMRT, GP... more;CCM 222; +EGD 220-01GPM;Game Studio I;3;0;MTH;8:30AM-9:45AM;Peter Wehr; 1/16 - 5/03;All - GDES, GMRT, GP... more;CCM 222; +EGD 220-01GS;Game Studio I;3;0;MTH;8:30AM-9:45AM;Peter Wehr; 1/16 - 5/03;All - GDES, GMRT, GP... more;CCM 222; +EGD 220-01IN;Game Studio I;3;0;MTH;8:30AM-9:45AM;Peter Wehr; 1/16 - 5/03;All - GDES, GMRT, GP... more;CCM 222; +EGD 220-01PR;Game Studio I;3;0;MTH;8:30AM-9:45AM;Peter Wehr; 1/16 - 5/03;All - GDES, GMRT, GP... more;CCM 222; +EGD 220-02AA;Game Studio I;3;-1;TF;8:30AM-9:45AM;Peter Wehr; 1/16 - 5/03;All - GDES, GMRT, GP... more;CCM 222; +EGD 220-02GD;Game Studio I;3;0;TF;8:30AM-9:45AM;Peter Wehr; 1/16 - 5/03;All - GDES, GMRT, GP... more;CCM 222; +EGD 220-02GPM;Game Studio I;3;0;TF;8:30AM-9:45AM;Peter Wehr; 1/16 - 5/03;All - GDES, GMRT, GP... more;CCM 222; +EGD 220-02GS;Game Studio I;3;0;TF;8:30AM-9:45AM;Peter Wehr; 1/16 - 5/03;All - GDES, GMRT, GP... more;CCM 222; +EGD 220-02IN;Game Studio I;3;2;TF;8:30AM-9:45AM;Peter Wehr; 1/16 - 5/03;All - GDES, GMRT, GP... more;CCM 222; +EGD 220-02PR;Game Studio I;3;1;TF;8:30AM-9:45AM;Peter Wehr; 1/16 - 5/03;All - GDES, GMRT, GP... more;CCM 222; +EGD 220-03AA;Game Studio I;3;0;MTH;10AM-11:15AM;Peter Wehr; 1/16 - 5/03;All - GDES, GMRT, GP... more;CCM 222; +EGD 220-03GD;Game Studio I;3;0;MTH;10AM-11:15AM;Peter Wehr; 1/16 - 5/03;All - GDES, GMRT, GP... more;CCM 222; +EGD 220-03GPM;Game Studio I;3;0;MTH;10AM-11:15AM;Peter Wehr; 1/16 - 5/03;All - GDES, GMRT, GP... more;CCM 222; +EGD 220-03GS;Game Studio I;3;0;MTH;10AM-11:15AM;Peter Wehr; 1/16 - 5/03;All - GDES, GMRT, GP... more;CCM 222; +EGD 220-03IN;Game Studio I;3;0;MTH;10AM-11:15AM;Peter Wehr; 1/16 - 5/03;All - GDES, GMRT, GP... more;CCM 222; +EGD 220-03PR;Game Studio I;3;0;MTH;10AM-11:15AM;Peter Wehr; 1/16 - 5/03;All - GDES, GMRT, GP... more;CCM 222; +EGD 220-04AA;Game Studio I;3;2;TF;10AM-11:15AM;Tracy Seamster; 1/16 - 5/03;All - GDES, GMRT, GP... more;CCM 222; +EGD 220-04GD;Game Studio I;3;-1;TF;10AM-11:15AM;Tracy Seamster; 1/16 - 5/03;All - GDES, GMRT, GP... more;CCM 222; +EGD 220-04GS;Game Studio I;3;0;TF;10AM-11:15AM;Tracy Seamster; 1/16 - 5/03;All - GDES, GMRT, GP... more;CCM 222; +EGD 220-04IN;Game Studio I;3;0;TF;10AM-11:15AM;Tracy Seamster; 1/16 - 5/03;All - GDES, GMRT, GP... more;CCM 222; +EGD 220-04PR;Game Studio I;3;0;TF;10AM-11:15AM;Tracy Seamster; 1/16 - 5/03;All - GDES, GMRT, GP... more;CCM 222; +EGD 220-05AA;Game Studio I;3;-1;MTH;8:30AM-9:45AM;Dana Steinhoff; 1/16 - 5/03;All - GDES, GMRT, GP... more;CCM 224; +EGD 220-05GD;Game Studio I;3;0;MTH;8:30AM-9:45AM;Dana Steinhoff; 1/16 - 5/03;All - GDES, GMRT, GP... more;CCM 224; +EGD 220-05GS;Game Studio I;3;0;MTH;8:30AM-9:45AM;Dana Steinhoff; 1/16 - 5/03;All - GDES, GMRT, GP... more;CCM 224; +EGD 220-05PR;Game Studio I;3;1;MTH;8:30AM-9:45AM;Dana Steinhoff; 1/16 - 5/03;All - GDES, GMRT, GP... more;CCM 224; +EGD 220-06AA;Game Studio I;3;0;TF;8:30AM-9:45AM;Robin Lloyd-Miller; 1/16 - 5/03;All - GDES, GMRT, GP... more;CCM 224; +EGD 220-06GD;Game Studio I;3;-3;TF;8:30AM-9:45AM;Robin Lloyd-Miller; 1/16 - 5/03;All - GDES, GMRT, GP... more;CCM 224; +EGD 220-06GS;Game Studio I;3;0;TF;8:30AM-9:45AM;Robin Lloyd-Miller; 1/16 - 5/03;All - GDES, GMRT, GP... more;CCM 224; +EGD 220-06IN;Game Studio I;3;2;TF;8:30AM-9:45AM;Robin Lloyd-Miller; 1/16 - 5/03;All - GDES, GMRT, GP... more;CCM 224; +EGD 220-06PR;Game Studio I;3;0;TF;8:30AM-9:45AM;Robin Lloyd-Miller; 1/16 - 5/03;All - GDES, GMRT, GP... more;CCM 224; +EGD 220-07AA;Game Studio I;3;-1;MTH;10AM-11:15AM;Dana Steinhoff; 1/16 - 5/03;All - GDES, GMRT, GP... more;CCM 224; +EGD 220-07GD;Game Studio I;3;-1;MTH;10AM-11:15AM;Dana Steinhoff; 1/16 - 5/03;All - GDES, GMRT, GP... more;CCM 224; +EGD 220-07GS;Game Studio I;3;0;MTH;10AM-11:15AM;Dana Steinhoff; 1/16 - 5/03;All - GDES, GMRT, GP... more;CCM 224; +EGD 220-07PR;Game Studio I;3;0;MTH;10AM-11:15AM;Dana Steinhoff; 1/16 - 5/03;All - GDES, GMRT, GP... more;CCM 224; +EGD 220-08AA;Game Studio I;3;2;TF;10AM-11:15AM;Christopher Mendenhall; 1/16 - 5/03;All - GDES, GMRT, GP... more;CCM 224; +EGD 220-08GD;Game Studio I;3;1;TF;10AM-11:15AM;Christopher Mendenhall; 1/16 - 5/03;All - GDES, GMRT, GP... more;CCM 224; +EGD 220-08IN;Game Studio I;3;2;TF;10AM-11:15AM;Christopher Mendenhall; 1/16 - 5/03;All - GDES, GMRT, GP... more;CCM 224; +EGD 220-08PR;Game Studio I;3;0;TF;10AM-11:15AM;Christopher Mendenhall; 1/16 - 5/03;All - GDES, GMRT, GP... more;CCM 224; +EGD 320-01AA;Game Studio II;3;1;W;9AM-11:45AM;Dana Steinhoff; 1/16 - 5/03;GDES.BS, GART.BS, GP... more;CCM 222; +EGD 320-01GD;Game Studio II;3;3;W;9AM-11:45AM;Dana Steinhoff; 1/16 - 5/03;GDES.BS, GART.BS, GP... more;CCM 222; +EGD 320-01GPM;Game Studio II;3;1;W;9AM-11:45AM;Dana Steinhoff; 1/16 - 5/03;GDES.BS, GART.BS, GP... more;CCM 222; +EGD 320-01GS;Game Studio II;3;-1;W;9AM-11:45AM;Dana Steinhoff; 1/16 - 5/03;GDES.BS, GART.BS, GP... more;CCM 222; +EGD 320-01PR;Game Studio II;3;-1;W;9AM-11:45AM;Dana Steinhoff; 1/16 - 5/03;GDES.BS, GART.BS, GP... more;CCM 222; +EGD 320-02AA;Game Studio II;3;0;W;12:15PM-3PM;Evan Janssen; 1/16 - 5/03;GDES.BS, GART.BS, GP... more;CCM 222; +EGD 320-02GD;Game Studio II;3;0;W;12:15PM-3PM;Evan Janssen; 1/16 - 5/03;GDES.BS, GART.BS, GP... more;CCM 222; +EGD 320-02GPM;Game Studio II;3;1;W;12:15PM-3PM;Evan Janssen; 1/16 - 5/03;GDES.BS, GART.BS, GP... more;CCM 222; +EGD 320-02GS;Game Studio II;3;0;W;12:15PM-3PM;Evan Janssen; 1/16 - 5/03;GDES.BS, GART.BS, GP... more;CCM 222; +EGD 320-02IN;Game Studio II;3;1;W;12:15PM-3PM;Evan Janssen; 1/16 - 5/03;GDES.BS, GART.BS, GP... more;CCM 222; +EGD 320-02PR;Game Studio II;3;0;W;12:15PM-3PM;Evan Janssen; 1/16 - 5/03;GDES.BS, GART.BS, GP... more;CCM 222; +EGD 320-03AA;Game Studio II;3;0;W;9AM-11:45AM;Robert Wakefield; 1/16 - 5/03;GDES.BS, GART.BS, GP... more;CCM 224; +EGD 320-03GD;Game Studio II;3;2;W;9AM-11:45AM;Robert Wakefield; 1/16 - 5/03;GDES.BS, GART.BS, GP... more;CCM 224; +EGD 320-03GPM;Game Studio II;3;0;W;9AM-11:45AM;Robert Wakefield; 1/16 - 5/03;GDES.BS, GART.BS, GP... more;CCM 224; +EGD 320-03GS;Game Studio II;3;0;W;9AM-11:45AM;Robert Wakefield; 1/16 - 5/03;GDES.BS, GART.BS, GP... more;CCM 224; +EGD 320-03PR;Game Studio II;3;0;W;9AM-11:45AM;Robert Wakefield; 1/16 - 5/03;GDES.BS, GART.BS, GP... more;CCM 224; +EGD 320-04AA;Game Studio II;3;0;W;12:15PM-3PM;Jessie Gagnon; 1/16 - 5/03;GDES.BS, GART.BS, GP... more;CCM 224; +EGD 320-04GD;Game Studio II;3;1;W;12:15PM-3PM;Jessie Gagnon; 1/16 - 5/03;GDES.BS, GART.BS, GP... more;CCM 224; +EGD 320-04GPM;Game Studio II;3;0;W;12:15PM-3PM;Jessie Gagnon; 1/16 - 5/03;GDES.BS, GART.BS, GP... more;CCM 224; +EGD 320-04GS;Game Studio II;3;-1;W;12:15PM-3PM;Jessie Gagnon; 1/16 - 5/03;GDES.BS, GART.BS, GP... more;CCM 224; +EGD 320-04IN;Game Studio II;3;1;W;12:15PM-3PM;Jessie Gagnon; 1/16 - 5/03;GDES.BS, GART.BS, GP... more;CCM 224; +EGD 320-04PR;Game Studio II;3;-1;W;12:15PM-3PM;Jessie Gagnon; 1/16 - 5/03;GDES.BS, GART.BS, GP... more;CCM 224; +EGD 320-05AA;Game Studio II;3;0;F;11:30AM-2:15PM;Dana Steinhoff; 1/16 - 5/03;GDES.BS, GART.BS, GP... more;CCM 222; +EGD 320-05GD;Game Studio II;3;1;F;11:30AM-2:15PM;Dana Steinhoff; 1/16 - 5/03;GDES.BS, GART.BS, GP... more;CCM 222; +EGD 320-05GPM;Game Studio II;3;1;F;11:30AM-2:15PM;Dana Steinhoff; 1/16 - 5/03;GDES.BS, GART.BS, GP... more;CCM 222; +EGD 320-05GS;Game Studio II;3;-1;F;11:30AM-2:15PM;Dana Steinhoff; 1/16 - 5/03;GDES.BS, GART.BS, GP... more;CCM 222; +EGD 320-05PR;Game Studio II;3;1;F;11:30AM-2:15PM;Dana Steinhoff; 1/16 - 5/03;GDES.BS, GART.BS, GP... more;CCM 222; +EGD 320-102;Game Studio II;3;17;T;6PM-8:45PM;Rodolphe Recca; 1/15 - 5/03;GDES.BS, GART.BS, GP... more; +EGD 380B-01;Adv. Sem.: Game Development;3;0;T;10AM-12:45PM;Robin Perlah; 1/16 - 5/03;Game Design majors o... more;MCLC 105A; +EGD 380B-02;Advanced Seminar;3;-1;M;5:30PM-8:15PM;John Levee; 1/16 - 5/03;Game Design majors o... more;CCM 402; +EGD 420-01;Game Studio III;5;72;M;2:30PM-5:15PM;Eric Winebrenner; 1/16 - 5/03;CCC-410EGD with a mi... more;CCM 222; +EGD 420-02;Game Studio III;5;-16;M;2:30PM-5:15PM;Ryan Huggins; 1/16 - 5/03;CCC-410EGD with a mi... more;CCM 224; +EGD 420-04;Game Studio III;5;-16;TH;2:30PM-5:15PM;Shannon Mitchell; 1/16 - 5/03;CCC-410EGD with a mi... more;CCM 222; +EGD 420-05;Game Studio III;5;-17;TH;2:30PM-5:15PM;Jennifer Vincent; 1/16 - 5/03;CCC-410EGD with a mi... more;CCM 224; +EGD 420-51;Game Studio III;5;-20;M;5:30PM-8:15PM;Edmar Mendizabal; 1/16 - 5/03;CCC-410EGD with a mi... more;FOST 104; +EHS 210-01SL;Social Justice Intensive;1;-6;M;1PM-1:50PM;Jean-Marie Severance; 1/16 - 3/29;EHS 100 is a prerequ... more;CCM 442; +EHS 210-03SL;Social Justice Intensive;1;-6;T;4PM-4:50PM;Valerie Esposito; 1/16 - 3/29;EHS 100 is a prerequ... more;JOYC 202; +EHS 230-01;Self Collective Care Soc Ch;1;0;MTH;2:30PM-3:45PM;Valerie Esposito; 1/16 - 2/16;None;JOYC 202; +EHS 230-02;Self Collective Care Soc Ch;1;11;TF;11:30AM-12:45PM;Valerie Esposito; 3/25 - 4/26;None;JOYC 212; +EHS 490-81;EHS Internship Experience;3;0;TBA;Stephen Miller; 1/16 - 5/03;Students must comple... more; +ENG 260-01;Survey of Drama;3;10;W;9AM-11:45AM;Christopher Tebbetts; 1/16 - 5/03;ENG-112 or COR-125 o... more;CCM 305; +ENP 270-01;Food Systems and Policy;3;0;M;4PM-6:45PM;Kelly Dolan; 1/16 - 5/03;None;JOYC 302; +ENP 300-01;Place-Based Environ. Study;3;0;T;1PM-3:45PM;Valerie Esposito; 1/16 - 5/03;None;JOYC 212; +ENP 360-51;Environmental Law;3;4;W;5:30PM-8:15PM;Salvatore Spinosa; 1/16 - 5/03;60 completed credits... more;JOYC 301; +EVT 497-81;Event Planning;3;0;TBA;Nancy Kerr; 1/16 - 5/03;None; +FIN 240-01;Financial Management I;3;11;MTH;8:30AM-9:45AM;Frederick Burkhardt; 1/16 - 5/03;Take ACC-135;GBTC 114; +FIN 240-02;Financial Management I;3;-1;MTH;10AM-11:15AM;Frederick Burkhardt; 1/16 - 5/03;Take ACC-135;GBTC 114; +FIN 300-01;Investments;3;4;TF;1PM-2:15PM;Frederick Burkhardt; 1/16 - 5/03;ACC-135;GBTC 217; +FLM 100-51;Film Studies: Screenings;1;38;W;5:30PM-8:15PM;Mira Niagolova; 1/16 - 5/03;None;CCM 305; +FLM 125-01;Audio Production for Film;3;-2;T;2:30PM-5:15PM;Matthew Parillo; 1/16 - 5/03;None;CCM 101; +FLM 125-51;Audio Production for Film;3;0;T;5:30PM-8:15PM;Michael DiBiasio; 1/16 - 5/03;None;CCM 101; +FLM 128-01;Screenwriting I;3;0;T;8:30AM-11:15AM;Julia Swift; 1/16 - 5/03;None;GBTC 206; +FLM 128-02;Screenwriting I;3;0;W;9AM-11:45AM;Scott Tuft; 1/16 - 5/03;None;JOYC 212; +FLM 128-03;Screenwriting I;3;0;TH;8:30AM-11:15AM;Scott Tuft; 1/16 - 5/03;None;GBTC 206; +FLM 211-01;Film History II;3;15;MTH;5:30PM-8:15PM,
2:30PM-3:45PM;Matthew Parillo; 1/16 - 5/03;Take FLM-210 OR any ... more;GBTC 112; +FLM 211-02;Film History II;3;2;MTH;5:30PM-8:15PM,
4PM-5:15PM;Matthew Parillo; 1/16 - 5/03;Take FLM-210 OR any ... more;GBTC 112; +FLM 215-01;Filmmaking I;3;-1;M;8:30AM-11:15AM;Mira Niagolova; 1/16 - 5/03;Film majors only. Co... more;FOST 101; +FLM 215-02;Filmmaking I;3;1;T;8:30AM-11:15AM;Mira Niagolova; 1/16 - 5/03;Film majors only. Co... more;FOST 101; +FLM 225-01;Cinematography and Lighting;3;-2;TTH;11:30AM-2:15PM,
5:30PM-6:45PM;Christian Acosta; 1/16 - 5/03;Take FLM-110 or BRD-... more;CCM 101; +FLM 225-02;Cinematography and Lighting;3;1;WTH;9AM-11:45AM,
7PM-8:15PM;Christian Acosta; 1/16 - 5/03;Take FLM-110 or BRD-... more;CCM 101; +FLM 301-01;Topics in Cinema;3;3;T;11:30AM-2:15PM;Mark Osborne; 1/16 - 5/03;This course is only ... more;CCM 305; +FLM 310-51;Production Management;3;0;M;5:30PM-8:15PM;Danielle Hazelton; 1/16 - 5/03;Complete 36 credits.;FOST 101; +FLM 325-01;Advanced Cinematography;3;-2;TH;1PM-3:45PM;Dillon Toole; 1/16 - 5/03;FLM-225 or permissio... more;CCM 101; +FLM 330-01;Video Comp Special Effects;3;7;F;8:30AM-11:15AM;Ryan Dunleavy; 1/16 - 5/03;Complete FLM-230;FOST 101; +FLM 330-02;Video Comp Special Effects;3;3;M;11:30AM-2:15PM;Ryan Dunleavy; 1/16 - 5/03;Complete FLM-230;FOST 101; +FLM 428-01;Screenwriting III;3;2;M;2:30PM-5:15PM;Michael DiBiasio; 1/16 - 5/03;FLM-328;FOST 101; +FOR 100-01;Intro to Cybercrime DF;3;3;MTH;10AM-11:15AM;Joseph Letourneau; 1/16 - 5/03;None;GBTC 117; +FOR 100-02;Intro to Cybercrime DF;3;0;TF;11:30AM-12:45PM;Joseph Letourneau; 1/16 - 5/03;None;GBTC 117; +FOR 120-01;Intro. to DF Analysis;3;5;MTH;1PM-2:15PM;Amy Keigwin; 1/16 - 5/03;Complete FOR-100 wit... more;GBTC 117; +FOR 120-02;Intro. to DF Analysis;3;-1;TF;4PM-5:15PM;Amy Keigwin; 1/16 - 5/03;Complete FOR-100 wit... more;GBTC 117; +FOR 230-01;Operating System Forensics I;3;-6;MTH;11:30AM-12:45PM;Mariam Khader; 1/16 - 5/03;Complete FOR-120 wit... more;GBTC 117; +FOR 230-02;Operating System Forensics I;3;-4;TF;2:30PM-3:45PM;Mariam Khader; 1/16 - 5/03;Complete FOR-120 wit... more;GBTC 117; +FOR 300-51;Special Topics in DF;1;-1;TH;5:30PM-8:15PM;Thomas Claflin; 2/19 - 3/29;FOR-120 or by permis... more;JOYC 202; +FOR 350-01;Malware Analysis IR;3;-9;MTH;2:30PM-3:45PM;Ali Hadi; 1/16 - 5/03;(FOR-230 with C or b... more;GBTC 117; +FOR 370-01;File System Forensics;3;3;TF;10AM-11:15AM;Ali Hadi; 1/16 - 5/03;FOR 230 with C or be... more;GBTC 117; +FOR 480-01;Digital Forensic Practicum;3;5;MTH;4PM-5:15PM;Ali Hadi; 1/16 - 5/03;Complete FOR-230 wit... more;GBTC 117; +GAA 105-01;Intro to 2D Digital Art;3;-2;T;8:30AM-11:15AM;Felipe Lega; 1/16 - 5/03;Game Art, Animation ... more;CCM 001; +GAA 125-01;Drawing for Realism I;3;0;M;10AM-12:45PM;Logan Pike; 1/16 - 5/03;Game Art, Animation ... more;SKFA 100; +GAA 135-01;Intro 3D Modeling Texturing;3;1;T;11:30AM-2:15PM;Christopher Mendenhall; 1/16 - 5/03;Game Art, Animation,... more;CCM 232; +GAA 135-02;Intro 3D Modeling Texturing;3;0;W;9AM-11:45AM;Felipe Lega; 1/16 - 5/03;Game Art, Animation,... more;CCM 232; +GAA 135-03;Intro 3D Modeling Texturing;3;-1;W;12:15PM-3PM;Joshua Stutts; 1/16 - 5/03;Game Art, Animation,... more;CCM 232; +GAA 135-04;Intro 3D Modeling Texturing;3;-1;TH;11:30AM-2:15PM;Christopher Mendenhall; 1/16 - 5/03;Game Art, Animation,... more;CCM 232; +GAA 175-01;Intro to Animation;3;-2;M;8:30AM-11:15AM;Nathan Walpole; 1/16 - 5/03;Game Art, Animation,... more;CCM 001; +GAA 175-02;Intro to Animation;3;0;TH;8:30AM-11:15AM;Felipe Lega; 1/16 - 5/03;Game Art, Animation,... more;CCM 001; +GAA 175-03;Intro to Animation;3;-1;F;8:30AM-11:15AM;Nathan Walpole; 1/16 - 5/03;Game Art, Animation,... more;CCM 001; +GAA 235-01;3D Modeling;3;8;T;11:30AM-2:15PM;Joshua Buck; 1/16 - 5/03;Take GAA-135, grade ... more;CCM 001; +GAA 245-01;Concept Painting, Foundations;3;6;T;2:30PM-5:15PM;Benjamin Jelter; 1/16 - 5/03;Complete GAA-225.;CCM 001; +GAA 245-02;Concept Painting, Foundations;3;1;W;9AM-11:45AM;Benjamin Jelter; 1/16 - 5/03;Complete GAA-225.;CCM 001; +GAA 245-03;Concept Painting, Foundations;3;9;TH;2:30PM-5:15PM;Logan Pike; 1/16 - 5/03;Complete GAA-225.;CCM 001; +GAA 255-01;3D Modeling II;3;3;M;11:30AM-2:15PM;Joshua Stutts; 1/16 - 5/03;Complete GAA-235 wit... more;CCM 001; +GAA 255-02;3D Modeling II;3;4;F;11:30AM-2:15PM;Joshua Stutts; 1/16 - 5/03;Complete GAA-235 wit... more;CCM 001; +GAA 275-01;3D Animation I;3;10;W;12:15PM-3PM;Nathan Walpole; 1/16 - 5/03;Complete GAA-175 wit... more;CCM 001; +GAA 345-01;3D Character Development;3;14;TH;11:30AM-2:15PM;Joshua Stutts; 1/16 - 5/03;Complete GAA-255 min... more;CCM 001; +GAA 360-01;Procedural 3D Modeling;3;4;M;11:30AM-2:15PM;Jo Ann Patel; 1/16 - 5/03;Take GAA-135 grade C... more;CCM 232; +GAA 380-01;Adv Sem: MoCap Animation;3;1;T;8:30AM-11:15AM;Nathan Walpole; 1/16 - 5/03;60 credits completed... more;CCM 232; +GAA 380-02;Adv Seminar: Game Art;3;0;F;8:30AM-11:15AM;Jennifer Carlin; 1/16 - 5/03;60 credits completed... more;CCM 232; +GAA 380-03;Adv Seminar: Game Art;3;1;F;11:30AM-2:15PM;Joshua Buck; 1/16 - 5/03;60 credits completed... more;CCM 232; +GAA 415-01;Sr Portfolio: Game Art;3;1;M;8:30AM-11:15AM;Joshua Buck; 1/16 - 5/03;90 credits completed... more;CCM 232; +GAA 415-02;Sr Portfolio: Game Art;3;0;TH;8:30AM-11:15AM;Joshua Buck; 1/16 - 5/03;90 credits completed... more;CCM 232; +GBP 310-01;Esports Management;3;17;MTH;10AM-11:15AM;Christian Konczal; 1/16 - 5/03;Game Business and Pu... more;CCM 444; +GMD 100-01;Visual Comm. for Game Design;3;-1;MTH;1PM-2:15PM;Tracy Seamster; 1/16 - 5/03;Game Design majors o... more;FOST 104; +GMD 100-02;Visual Comm. for Game Design;3;-4;TF;2:30PM-3:45PM;Tracy Seamster; 1/16 - 5/03;Game Design majors o... more;CCM 222; +GMD 100-03;Visual Comm. for Game Design;3;-4;MTH;4PM-5:15PM;Tracy Seamster; 1/16 - 5/03;Game Design majors o... more;FOST 104; +GMD 110-01;Introduction to Game Design;3;2;TF;10AM-11:15AM;Greg Bemis; 1/16 - 5/03;Game Design, CREM or... more;FOST 104; +GMD 120-01;Creativity and Play;3;0;MTH;10AM-11:15AM;Samara Fantie; 1/16 - 5/03;Game Design and CREM... more;FOST 100; +GMD 120-02;Creativity and Play;3;0;MTH;11:30AM-12:45PM;Kenneth Howell; 1/16 - 5/03;Game Design and CREM... more;CCM 424; +GMD 120-03;Creativity and Play;3;3;MTH;8:30AM-9:45AM;Samara Fantie; 1/16 - 5/03;Game Design and CREM... more;CCM 444; +GMD 120-04;Creativity and Play;3;-1;MTH;2:30PM-3:45PM;Kenneth Howell; 1/16 - 5/03;Game Design and CREM... more;WICK 100; +GMD 200-01;Game Technology I;3;1;T;11:30AM-2:15PM;Joseph Manley; 1/16 - 5/03;CSI-140 or CSI-160 a... more;FOST 104; +GMD 200-02;Game Technology I;3;0;T;2:30PM-5:15PM;Joseph Manley; 1/16 - 5/03;CSI-140 or CSI-160 a... more;CCM 224; +GMD 200-03GPR;Game Technology I;3;4;MTH;11:30AM-12:45PM;Eric Winebrenner; 1/16 - 5/03;CSI-140 or CSI-160 a... more;JOYC 101; +GMD 200-04GPR;Game Technology I;3;1;TF;4PM-5:15PM;Eric Winebrenner; 1/16 - 5/03;CSI-140 or CSI-160 a... more;JOYC 101; +GMD 200-51;Game Technology I;3;2;W;5:30PM-8:15PM;Robert Wakefield; 1/16 - 5/03;CSI-140 or CSI-160 a... more;FOST 104; +GMD 200-52;Game Technology I;3;2;TH;5:30PM-8:15PM;Robert Wakefield; 1/16 - 5/03;CSI-140 or CSI-160 a... more;FOST 104; +GMD 230-01;Interactive Narrative I;3;-3;M;8:30AM-11:15AM;Kellan Bachus; 1/16 - 5/03;Take GMD-110, WRT-12... more;CCM 233; +GMD 240-01;Level Design;3;0;T;11:30AM-2:15PM;John Boyd; 1/16 - 5/03;Game Design majors o... more;CCM 222; +GMD 240-02;Level Design;3;0;W;12:15PM-3PM;John Boyd; 1/16 - 5/03;Game Design majors o... more;FOST 104; +GMD 240-03;Level Design;3;6;TH;8:30AM-11:15AM;John Boyd; 1/16 - 5/03;Game Design majors o... more;CCM 233; +GMD 320-01;Game Sys. Experience Design;3;7;T;11:30AM-2:15PM;Greg Bemis; 1/16 - 5/03;Game Design majors o... more;CCM 224; +GMD 320-03;Game Sys. Experience Design;3;0;TH;11:30AM-2:15PM;Greg Bemis; 1/16 - 5/03;Game Design majors o... more;CCM 224; +GMD 320-102;Game Sys. Experience Design;3;17;T;2PM-4:45PM;Kaermack Polewska; 1/15 - 5/03;Game Design majors o... more; +GMD 350-01;Interactive Narrative II;3;5;M;11:30AM-2:15PM;Kellan Bachus; 1/16 - 5/03;Complete GMD-230.;CCM 233; +GMD 380-01;Adv Sem: Creating Atmosphere;3;1;W;5:30PM-8:15PM;Benjamin Throop; 1/16 - 5/03;Game Design majors o... more;CCM 222; +GMD 380-02;Advanced Seminar: Game Design;3;0;W;9AM-11:45AM;John Boyd; 1/16 - 5/03;Game Design majors o... more;CCM 233; +GMD 380-04;AdvSem: Interactive Narrative;3;0;T;2:30PM-5:15PM;Kellan Bachus; 1/16 - 5/03;Game Design majors o... more;CCM 233; +GMD 410-01;Senior Portfolio: Game Design;3;0;W;9AM-11:45AM;Greg Bemis; 1/16 - 5/03;90 credits completed... more;FOST 104; +GMD 410-02;Senior Portfolio: Game Design;3;7;TH;11:30AM-2:15PM;Joseph Manley; 1/16 - 5/03;90 credits completed... more;CCM 233; +GMS 110-01;Intro to Game Engines for Sou;3;0;T;10AM-12:45PM;John Levee; 1/16 - 5/03;Take SON-120;GBTC 012; +GMS 110-02;Intro to Game Engines for Sou;3;1;TH;2:30PM-5:15PM;John Levee; 1/16 - 5/03;Take SON-120;GBTC 012; +GMS 300-01;Game Snd Des II;3;11;W;12:15PM-3PM;John Levee; 1/16 - 5/03;Take SON-200;GBTC 012; +GPR 250-01;Game Architecture;3;1;MTH;2:30PM-3:45PM;Dean Lawson; 1/16 - 5/03;Complete CSI-240 wit... more;JOYC 101; +GPR 250-02;Game Architecture;3;-2;TF;2:30PM-3:45PM;Dean Lawson; 1/16 - 5/03;Complete CSI-240 wit... more;JOYC 101; +GPR 250-03;Game Architecture;3;0;MTH;4PM-5:15PM;Dean Lawson; 1/16 - 5/03;Complete CSI-240 wit... more;JOYC 101; +GPR 300-01;Inter Graphics Anim Prog;3;1;TF;10AM-11:15AM;Eric Winebrenner; 1/16 - 5/03;GPR-200 AND (GPR-250... more;JOYC 101; +GPR 300-02;Inter Graphics Anim Prog;3;6;MTH;10AM-11:15AM;Eric Winebrenner; 1/16 - 5/03;GPR-200 AND (GPR-250... more;JOYC 101; +GPR 430-01;Networking for Online Games;3;2;TF;11:30AM-12:45PM;Scott Barrett; 1/16 - 5/03;Complete GPR-200, GP... more;JOYC 101; +GPR 430-02;Networking for Online Games;3;1;TF;1PM-2:15PM;Scott Barrett; 1/16 - 5/03;Complete GPR-200, GP... more;JOYC 101; +GPR 440-01;Advanced AI for Games;3;2;MTH;1PM-2:15PM;Alexandre Tolstenko Nogueira; 1/16 - 5/03;GPR-340, Minimum gra... more;JOYC 101; +GPR 470-02;Game Programmer's Portfolio;3;-7;W;12:15PM-3PM;Alexandre Tolstenko Nogueira; 1/16 - 5/03;Game Programming maj... more;JOYC 101; +INT 230-01;Import/Export;3;12;TF;4PM-5:15PM;Parthiv Patel; 1/16 - 5/03;INT-210;GBTC 217; +INT 320-01;International Finance Trade;3;11;TF;8:30AM-9:45AM;Ciaran Buckley; 1/16 - 5/03;Complete BUS-310, EC... more;CCM 442; +ITS 192-71;ITS Internship I;2;1;TBA;Zoltan Sachs; 2/19 - 5/03;None; +ITS 292-71;ITS Internship II;2;0;TBA;Zoltan Sachs; 2/19 - 5/03;Complete 30 credits; +IXD 200-01;Aesthetic Interactions;3;0;T;1PM-3:45PM;Kenneth Howell; 1/16 - 5/03;COMPLETE ONE OF THE ... more;CCM 426; +IXD 200-02;Aesthetic Interactions;3;-2;W;12:15PM-3PM;Kenneth Howell; 1/16 - 5/03;COMPLETE ONE OF THE ... more;CCM 426; +IXD 399-51;Sonic Circuits;3;4;TH;1PM-3:45PM;Alan Larsen; 1/16 - 5/03;57 completed credits... more;CCM 426; +LAN 140-01;Japanese I;3;-2;MTH;2:30PM-3:45PM;Sinyoung Evans; 1/16 - 5/03;None;GBTC 206; +LAN 340-01;Japanese III;3;5;MTH;4PM-5:15PM;Sinyoung Evans; 1/16 - 5/03;LAN-240 or permissio... more;GBTC 206; +LEG 120-51;Business Law;3;0;M;5:30PM-8:15PM;Jeffrey Messina; 1/16 - 5/03;None;JOYC 304; +LEG 160-01;Contracts;3;11;MTH;11:30AM-12:45PM;Eric Friedman; 1/16 - 5/03;None;CCM 221; +LEG 310-01;Wills, Trusts Estates;3;7;MTH;1PM-2:15PM;Eric Friedman; 1/16 - 5/03;LEG-210;CCM 221; +LEG 360-51;Environmental Law;3;6;W;5:30PM-8:15PM;Salvatore Spinosa; 1/16 - 5/03;60 completed credits... more;JOYC 301; +LEG 390-81;Law Externship;3;20;TBA;Stephen Miller; 1/16 - 5/03;60 completed credits... more; +LEG 410-01;US Constitutional Law;3;10;MTH;10AM-11:15AM;Eric Friedman; 1/16 - 5/03;Must complete 60 cre... more;CCM 221; +MGT 140-01;Intro to Game Develop. Mgmt;3;5;MTH;2:30PM-3:45PM;Peter Wehr; 1/16 - 5/03;For Game Production ... more;CCM 233; +MGT 150-01;Exploring Analytics;3;11;TF;8:30AM-9:45AM;Jennifer Vincent; 1/16 - 5/03;Complete MTH-180;WICK 100; +MGT 150-02;Exploring Analytics;3;1;TF;10AM-11:15AM;Jennifer Vincent; 1/16 - 5/03;Complete MTH-180;WICK 100; +MGT 210-01;Catalyze Positive Org Behavio;3;12;MTH;10AM-11:15AM;Lindsey Godwin; 1/16 - 5/03;None;GBTC 217; +MGT 260-01;Project Mgmt Team Leadership;3;1;M;2:30PM-5:15PM;Lindsey Godwin; 1/16 - 5/03;Must complete 30 cre... more;GBTC 112; +MGT 265-51;Information Systems for Mgmt;3;4;MW;5:30PM-6:45PM;Kenneth Heskett; 1/16 - 5/03;Complete 30 credits ... more;GBTC 112; +MGT 270-51;Business of Entrepreneurship;3;1;T;5:30PM-8:15PM;Charles Bush; 1/16 - 5/03;Complete BUS-110 and... more;HULA 100; +MGT 290-81;Business Career Internship;3;22;TBA;Barrie Silver; 1/16 - 5/03;MGT-210 Must complet... more; +MGT 320-01;Product/Operation Management;3;11;MTH;4PM-5:15PM;Marie Segares; 1/16 - 5/03;MTH-180, ACC-140;JOYC 102; +MGT 330-01;HRM I:Talent/Plng/Acquisition;3;17;TF;8:30AM-9:45AM;Joseph O'Grady; 1/16 - 5/03;None;GBTC 217; +MGT 331-01;HRM II:Talent/Dev Retention;3;20;TF;1PM-2:15PM;Joseph O'Grady; 1/16 - 5/03;MGT-330;GBTC 112; +MGT 365-01;Entrepreneurship: New Venture;3;16;TF;10AM-11:15AM;Charles Bush; 1/16 - 5/03;Complete MGT-270;GBTC 114; +MGT 390-81;Advanced Business Internship;3;16;TBA;Barrie Silver; 1/16 - 5/03;Must have completed ... more; +MGT 425-01;Problem Analysis/Decision Mkg.;3;9;MTH;11:30AM-12:45PM;Joseph O'Grady; 1/16 - 5/03;Must complete 75 cre... more;GBTC 112; +MGT 460-01;Business Policy/Strategic Mgt;3;17;TF;2:30PM-3:45PM;Parthiv Patel; 1/16 - 5/03;Complete 90 and be a... more;GBTC 217; +MKT 110-01;Introduction to Marketing;3;11;TF;2:30PM-3:45PM;Charles Bush; 1/16 - 5/03;None;GBTC 114; +MKT 111-51;Exploring Marketing I;1;18;T;5:30PM-8:15PM;Teresa Anderson; 1/16 - 2/16;Marketing Major (fir... more;GBTC 112; +MKT 112-51;Exploring Marketing II;1;18;T;5:30PM-8:15PM;Teresa Anderson; 2/19 - 3/29;MKT 111; Marketing M... more;GBTC 114; +MKT 210-01;Consumer Behavior;3;18;MTH;10AM-11:15AM;Robert Bloch; 1/16 - 5/03;Complete BUS-120 or ... more;GBTC 112; +MKT 250-51;Intro. to Digital Marketing;3;11;MW;5:30PM-6:45PM;Thomas Funk; 1/16 - 5/03;Complete BUS-120 or ... more;JOYC 305; +MKT 280-01;Activist Marketing;3;13;MTH;11:30AM-12:45PM;Barrie Silver; 1/16 - 5/03;Complete either BUS-... more;GBTC 217; +MKT 290-81;Marketing Internship;3;21;TBA;Barrie Silver; 1/16 - 5/03;Marketing Majors and... more; +MKT 430-01;Strategic Community Mgt.;3;14;TF;2:30PM-3:45PM;Barrie Silver; 1/16 - 5/03;Complete MKT 250 and... more;CCM 444; +MKT 490-81;Advanced Marketing Internship;4;24;TBA;Barrie Silver; 1/16 - 5/03;Approval of Marketin... more; +MTH 115-01;Math for ProbSolv/DecMaking;3;10;MTH;8:30AM-9:45AM;Michael Weinberg; 1/16 - 5/03;None;JOYC 205; +MTH 115-02;Math for ProbSolv/DecMaking;3;0;MTH;10AM-11:15AM;Michael Weinberg; 1/16 - 5/03;None;JOYC 205; +MTH 115-03;Math for ProbSolv/DecMaking;3;0;MTH;2:30PM-3:45PM;Brandon Tries; 1/16 - 5/03;None;JOYC 205; +MTH 115-04;Math for ProbSolv/DecMaking;3;-13;MTH;4PM-5:15PM;Lindsay Day; 1/16 - 5/03;None;JOYC 205; +MTH 115-51;Math for ProbSolv/DecMaking;3;-1;MW;5:30PM-6:45PM;Lindsay Day; 1/16 - 5/03;None;JOYC 205; +MTH 180-02;Statistics, Introduction to;3;0;MTH;11:30AM-12:45PM;Michael Opperman; 1/16 - 5/03;None;JOYC 203; +MTH 180-03;Statistics, Introduction to;3;0;MTH;1PM-2:15PM;Brandon Tries; 1/16 - 5/03;None;JOYC 205; +MTH 180-04;Statistics, Introduction to;3;0;MTH;2:30PM-3:45PM;Warren Sides; 1/16 - 5/03;None;JOYC 203; +MTH 180-06;Statistics, Introduction to;3;-1;TF;10AM-11:15AM;Warren Sides; 1/16 - 5/03;None;JOYC 203; +MTH 180-07;Statistics, Introduction to;3;-1;TF;11:30AM-12:45PM;Warren Sides; 1/16 - 5/03;None;JOYC 203; +MTH 180-10;Statistics, Introduction to;3;5;TF;8:30AM-9:45AM;Erin Milne; 1/16 - 5/03;None;JOYC 205; +MTH 230-02;Calculus I;3;0;TF;2:30PM-3:45PM;Michael Lambert; 1/16 - 5/03;Complete MTH-125 or ... more;JOYC 203; +MTH 240-01;Calculus II;3;-6;TF;1PM-2:15PM;Michael Lambert; 1/16 - 5/03;MTH-230;JOYC 203; +MTH 250-01;Matrices, Vectors, and 3D Math;3;-2;MTH;1PM-2:15PM;Michael Opperman; 1/16 - 5/03;MTH-230;MIC 308; +MTH 250-02;Matrices, Vectors, and 3D Math;3;3;MTH;2:30PM-3:45PM;Michael Opperman; 1/16 - 5/03;MTH-230;MIC 308; +MTH 270-01;Discrete Mathematics;3;8;TF;11:30AM-12:45PM;Melanie Brown; 1/16 - 5/03;Complete MTH-125 wit... more;JOYC 205; +MTH 275-01;Mathematical Cryptography;3;6;TF;1PM-2:15PM;Melanie Brown; 1/16 - 5/03;Complete MTH-125 OR ... more;JOYC 205; +MTH 280-01;Applied Statistics;3;5;W;12:15PM-3PM;Michael Opperman; 1/16 - 5/03;MTH-180;MIC 308; +MTH 315-01;Survey of Geometries;3;9;MTH;4PM-5:15PM;Warren Sides; 1/16 - 5/03;MTH-270;JOYC 203; +MTH 400-01;Advanced Topics in Math;3;-9;TF;2:30PM-3:45PM;Melanie Brown; 1/16 - 5/03;Take MTH-270;;JOYC 205; +MTH 491-81;Topology;3;0;TBA;Warren Sides; 1/16 - 5/03;None; +MTH 492-81;Abstract Algebra;3;0;TBA;Warren Sides; 1/16 - 5/03;None; +NET 150-01;Network Fundamentals;3;0;MTH;10AM-11:15AM;David Ginter; 1/16 - 5/03;None;FOST 202; +NET 150-03;Network Fundamentals;3;1;TF;10AM-11:15AM;David Ginter; 1/16 - 5/03;None;FOST 202; +NET 150-04;Network Fundamentals;3;-2;TF;11:30AM-12:45PM;David Ginter; 1/16 - 5/03;None;FOST 202; +NET 150-05;Network Fundamentals;3;-1;MTH;1PM-2:15PM;Adam Goldstein; 1/16 - 5/03;None;FOST 202; +NET 480-01;Advanced Topics in Networking;3;0;W;9AM-11:45AM;Ryan Gillen; 1/16 - 5/03;Complete NET-330 wit... more;JOYC 310; +PSY 100-01;Psychology, Introduction to;3;5;MTH;1PM-2:15PM;Gary Baker; 1/16 - 5/03;None;JOYC 302; +PSY 200-01;App Psy: Theory to Analyses;3;7;W;9AM-11:45AM;Barbara Colombo; 1/16 - 5/03;Take PSY-201 Take PS... more;JOYC 103; +PSY 202-01;Research Methods Analysis II;3;2;TF;10AM-11:15AM;Gary Baker; 1/16 - 5/03;PSY-201 and MTH-180.;JOYC 212; +PSY 210-01;Cognitive Psychology;3;0;MTH;11:30AM-12:45PM;Kimberly Quinn; 1/16 - 5/03;PSY-100 or 100-level... more;JOYC 102; +PSY 210-02;Cognitive Psychology;3;9;MTH;2:30PM-3:45PM;Kimberly Quinn; 1/16 - 5/03;PSY-100 or 100-level... more;WICK 101; +PSY 220-01;Developmental Psychology;3;0;T;4PM-6:45PM;Melissa McDuffie; 1/16 - 5/03;PSY-100 or COR-110.;JOYC 301; +PSY 290-01;Career Internship I;2;7;MTH;2:30PM-3:45PM;Barbara Colombo; 1/16 - 5/03;Complete PSY-115;JOYC 305; +PSY 330-01;Psychology and Law;3;8;MTH;10AM-11:15AM;Gary Baker; 1/16 - 5/03;Must have completed ... more;JOYC 302; +PSY 340-01;Behavioral Neuroscience;4;6;MTH;1PM-2:15PM;Barbara Colombo; 1/16 - 5/03;Complete SCI-115 and... more;JOYC 305; +PSY 450-01;Counseling Skills;3;6;TF;1PM-2:15PM;Melissa McDuffie; 1/16 - 5/03;PSY-205;JOYC 301; +SCI 115-01;Human Biology, Introduction to;4;0;TFT;1PM-2:15PM,
3PM-5PM;Sarah Beno; 1/16 - 5/03;None;JOYC 103; +SCI 140-01;Nutrition Fitness/Biology of;4;3;TFW;8:30AM-9:45AM,
9AM-11AM;Sarah Beno; 1/16 - 5/03;None;JOYC 103; +SCI 140-02;Nutrition Fitness/Biology of;4;0;TFW;10AM-11:15AM,
12PM-2PM;Sarah Beno; 1/16 - 5/03;None;JOYC 103; +SCI 150-01;Environmental Earth Sciences;4;1;MTHM;8:30AM-9:45AM,
12PM-2PM;Jennifer Supple; 1/16 - 5/03;None;JOYC 103; +SCI 150-51;Environmental Earth Sciences;4;2;TTH;5:30PM-8:15PM,
5:30PM-7:30PM;John Brawley; 1/16 - 5/03;None;FREE 102; +SCI 170-01;Forensic Science, Intro to;4;1;MTHW;11:30AM-12:45PM,
9AM-11AM;Alexandra Collins; 1/16 - 5/03;None;FREE 105; +SCI 170-02;Forensic Science, Intro to;4;0;MTHW;1PM-2:15PM,
12PM-2PM;Alexandra Collins; 1/16 - 5/03;None;JOYC 103; +SCI 170-51;Forensic Science, Intro to;4;0;MT;5:30PM-8:15PM,
5:30PM-7:30PM;Velpula Paul; 1/16 - 5/03;None;FREE 105; +SEC 250-01;Computer Network Security;3;-1;MTH;1PM-2:15PM;Joseph Letourneau; 1/16 - 5/03;Complete SEC-110 or ... more;GBTC 017; +SEC 250-02;Computer Network Security;3;2;MTH;2:30PM-3:45PM;Mariam Khader; 1/16 - 5/03;Complete SEC-110 or ... more;JOYC 310; +SEC 250-03;Computer Network Security;3;0;TF;1PM-2:15PM;Joseph Letourneau; 1/16 - 5/03;Complete SEC-110 or ... more;GBTC 017; +SEC 250-04;Computer Network Security;3;1;TF;2:30PM-3:45PM;Syed Ali; 1/16 - 5/03;Complete SEC-110 or ... more;GBTC 017; +SEC 260-01;Web and Applications Security;3;-4;TF;1PM-2:15PM;Furkan Paligu; 1/16 - 5/03;Complete NET-150 and... more;JOYC 310; +SEC 260-02;Web and Applications Security;3;-1;MTH;4PM-5:15PM;Furkan Paligu; 1/16 - 5/03;Complete NET-150 and... more;GBTC 017; +SEC 260-03;Web and Applications Security;3;-1;MTH;1PM-2:15PM;David Ginter; 1/16 - 5/03;Complete NET-150 and... more;JOYC 310; +SEC 300-71;Special Topic:Wireless Cyber;1;14;T;4PM-5:15PM;Adam Goldstein; 3/26 - 4/23; Complete SEC-250, N... more;JOYC 310; +SEC 335-51;Eth. Hacking Pen. Testing;3;-4;M;5:30PM-8:15PM;Furkan Paligu; 1/16 - 5/03;Complete SEC-260, SE... more;JOYC 310; +SEC 345-72;Information Assurance;3;1;M;4PM-5:15PM;Lakysha Patnode; 1/16 - 5/03;Complete SEC-250 wit... more;JOYC 310; +SEC 350-01;Network Security Controls;3;1;M;10AM-12:45PM;Syed Ali; 1/16 - 5/03;Complete SEC-250, SY... more;GBTC 017; +SEC 350-02;Network Security Controls;3;2;W;9AM-11:45AM;Syed Ali; 1/16 - 5/03;Complete SEC-250, SY... more;GBTC 017; +SEC 440-01;Systems Security;3;10;T;10AM-12:45PM;Adam Goldstein; 1/16 - 5/03;Complete SYS-265, NE... more;JOYC 310; +SEC 480-01;Adv Topics in Cyber Security;3;-2;W;9AM-11:45AM;Ryan Gillen; 1/16 - 5/03;Complete 90 credits ... more;JOYC 310; +SON 101-01;Sound Studio Production;3;1;FF;10AM-12:45PM,
10AM-12:45PM;Justin Croft; 1/16 - 5/03;Must have approval f... more;CCM 014; +SON 101-51;Sound Studio Production;3;0;THTH;5:30PM-8:15PM,
5:30PM-8:15PM;Justin Croft; 1/16 - 5/03;Must have approval f... more;CCM 014; +SON 120-01;Fundamentals of Digital Music;3;2;TF;1PM-2:15PM;Eric Sample; 1/16 - 5/03;None;GBTC 012; +SON 120-02;Fundamentals of Digital Music;3;1;TF;2:30PM-3:45PM;Eric Sample; 1/16 - 5/03;None;GBTC 012; +SON 131-01;History of Musical Innovation;3;2;MTH;1PM-2:15PM;Eric Sample; 1/16 - 5/03;None;GBTC 012; +SON 165-51;Business of Music, the;3;6;M;5:30PM-8:15PM;Malcolm Francis; 1/16 - 5/03;None;GBTC 012; +SON 282-01;Synthesis and Sound Design;3;1;W;9AM-11:45AM;Eric Sample; 1/16 - 5/03;None;GBTC 012; +SWK 140-01SL;Survey of Community Agencies;3;9;W;10AM-12:45PM;Tarn Foerg; 1/16 - 5/03;None;JOYC 304; +SWK 141-01SL;Community Experience;1;17;T;11:30AM-12:20PM;Tarn Foerg; 1/16 - 5/03;Only Social Work Maj... more;JOYC 103; +SWK 235-01;Human Behav: Person-in-Envir.;3;0;MTH;8:30AM-9:45AM;Alicia Cerasoli; 1/16 - 5/03;Complete 40 credits ... more;JOYC 301; +SWK 240-51;Family Violence;3;3;M;5:30PM-8:15PM;Jennifer Jorgenson; 1/16 - 5/03;None;JOYC 301; +SWK 250-71;Intro to Antiracist Practice;3;4;W;5:30PM-8:15PM;Joyce-Zoe Farley; 1/16 - 5/03;Complete 25 credits.;JOYC 302; +SWK 300-01;Policy Pract.:Local to Global;3;15;MTH;2:30PM-3:45PM;Sianay Clifford; 1/16 - 5/03;Must complete 50 cre... more;JOYC 301; +SWK 315-01;Generalist Practice II;3;5;MTH;1PM-2:15PM;Sianay Clifford; 1/16 - 5/03;Take SWK-310.;FREE 201; +SWK 495-71;Social Wk Field Experience II;4;15;TBA;Tarn Foerg; 1/16 - 5/03;Complete SWK-490 and... more; +SWK 495S-01;Int. Social Wk Field Seminar;1;11;M;11:30AM-12:20PM;Tarn Foerg; 1/16 - 5/03;Complete SWK-490 and... more;JOYC 202; +SYS 140-01;Systems Fundamentals;3;4;MTH;2:30PM-3:45PM;Eric Shore; 1/16 - 5/03;None;GBTC 017; +SYS 255-01;Sysadmin Net Services I;3;-8;TH;10AM-12:45PM;Syed Ali; 1/16 - 5/03;Complete NET-150 and... more;GBTC 017; +SYS 265-01;Sysadmin Net Services II;3;2;M;10AM-12:45PM;Joe Eastman; 1/16 - 5/03;Complete NET-215 and... more;JOYC 310; +SYS 265-02;Sysadmin Net Services II;3;0;TH;10AM-12:45PM;Joe Eastman; 1/16 - 5/03;Complete NET-215 and... more;JOYC 310; +SYS 265-03;Sysadmin Net Services II;3;0;W;12:15PM-3PM;Joe Eastman; 1/16 - 5/03;Complete NET-215 and... more;JOYC 310; +SYS 320-01;Automation and Scripting;3;1;F;10AM-12:45PM;Furkan Paligu; 1/16 - 5/03;Complete SYS-255 wit... more;JOYC 310; +SYS 360-01;Cloud Admin Deploy.;3;-5;W;12:15PM-3PM;Adam Goldstein; 1/16 - 5/03;Complete SYS-265;GBTC 017; +SYS 480-01;Adv Topics in SysAdmin;3;0;W;9AM-11:45AM;Ryan Gillen; 1/16 - 5/03;Complete 90 credits,... more;JOYC 310; +THE 140-01;Fundamentals of Acting;3;7;M;2:30PM-5:15PM;Paul Schnabel; 1/16 - 5/03;None;CCM 305; +VCD 110-01;Image Technology;3;-2;M;10AM-12:45PM;Emily Andrews; 1/16 - 5/03;None;CCM 426; +VCD 115-51VCD;The Digital Image;3;2;THT;6PM-8PM,
5:30PM-8:15PM;Andrew Frost; 1/16 - 5/03;None;CCM 426; +VCD 181-01;Design Solutions;3;1;W;9AM-11:45AM;Sheri Bannister; 1/16 - 5/03;None;CCM 426; +VCD 201-01;Intro to Typography;3;1;WW;9AM-11:45AM,
12:15PM-2:15PM;Michelle Hobbs; 1/16 - 5/03;VCD- 100 or approval... more;BARN 200; +VCD 201-02;Intro to Typography;3;2;FF;10AM-12:45PM,
1:45PM-3:45PM;Deborah Kehoe-Yergeau; 1/16 - 5/03;VCD- 100 or approval... more;BARN 200; +VCD 203-51;Form in Motion;3;0;M;5:30PM-8:15PM;Kevin Murakami; 1/16 - 5/03;None;GBTC 014; +VCD 203-52;Form in Motion;3;-1;TH;5:30PM-8:15PM;Kevin Murakami; 1/15 - 5/03;None;GBTC 014; +VCD 206-01;Web Design I;3;-3;FT;10AM-12:45PM,
10AM-12PM;Jamie Aponas; 1/16 - 5/03;VCD-100 or VCD-111;CCM 426; +VCD 220-01;Visual Creativity Meaning;3;-2;TF;1PM-2:15PM;Robin Perlah; 1/16 - 5/03;ART-120;GBTC 114; +VCD 250-01;Prof Comm Practice;1;9;M;10AM-10:50AM;Sarah Moore; 1/16 - 5/03;Complete 45 credits ... more;GBTC 206; +VCD 270-01;Intermediate Typography;3;0;THTH;10AM-12:45PM,
1:45PM-3:45PM;Suzanne Snyder; 1/16 - 5/03;VCD-201;BARN 200; +VCD 301-01;Advanced Typography;3;6;MM;1:45PM-3:45PM,
10AM-12:45PM;Suzanne Snyder; 1/16 - 5/03;Complete VCD-270;BARN 200; +VCD 302-01;Graphic Design/ObjectsSpaces;3;11;T;4PM-6:45PM;Dennis Healy; 1/16 - 5/03;VCD-201;BARN 200; +VCD 303-51;Illustration, Introduction to;3;6;M;5:30PM-8:15PM;Teresa Celemin; 1/16 - 5/03;ART-110 or GDD-110 o... more;CCM 434; +VCD 305-01;Publication Design II;3;2;TH;8:30AM-11:15AM;Matthew Douglas; 1/16 - 5/03;Complete VCD-205;CCM 426; +VCD 307-51;Form in Motion II;3;5;TH;5:30PM-8:15PM;Kevin Murakami; 1/16 - 5/03;Complete VCD-203 or ... more;GBTC 014; +VCD 400-01;Projects in Graphic Design II;3;12;TT;10AM-12:45PM,
1:45PM-3:45PM;Deborah Kehoe-Yergeau; 1/16 - 5/03;MMGD or GDDM or VCDS... more;BARN 200; +VCD 430-51;Creative Production Studio;3;10;MTH;4PM-6:45PM,
4PM-6PM;Rachel Hooper; 1/16 - 5/03;Complete 60 credits ... more;BARN 200; +VCD 450-01;Portfolio Studio;2;2;T;4PM-5:40PM;Deborah Kehoe-Yergeau; 1/16 - 5/03;Complete VCD-250. GD... more;BARN 100; +VCD 450-02;Portfolio Studio;2;2;F;4PM-5:40PM;Deborah Kehoe-Yergeau; 1/16 - 5/03;Complete VCD-250. GD... more;BARN 200; +WRT 120-01;Creative Writing, Introduction;3;0;MTH;1PM-2:15PM;James Ellefson; 1/16 - 5/03;ENG-111 OR COR-115;CCM 444; +WRT 120-02;Creative Writing, Introduction;3;-1;MTH;2:30PM-3:45PM;James Ellefson; 1/16 - 5/03;ENG-111 OR COR-115;CCM 444; +WRT 200-01;Fundamentals of Journalism;3;0;MTH;8:30AM-9:45AM;Rebecca Holt; 1/16 - 5/03;ENG-111 OR COR-115;CCM 442; +WRT 220-51;Creative Writing, Intermediate;3;0;TH;4PM-6:45PM;James Ellefson; 1/16 - 5/03;WRT-120;CCM 444; +WRT 231-01;Writing for the Workplace;3;2;TF;8:30AM-9:45AM;Sheila Liming; 1/16 - 5/03;None;CCM 424; +WRT 231-02;Writing for the Workplace;3;0;TF;10AM-11:15AM;Sheila Liming; 1/16 - 5/03;None;CCM 424; +WRT 231-03;Writing for the Workplace;3;4;MTH;8:30AM-9:45AM;Siobhan Neela-Stock; 1/16 - 5/03;None;CCM 424; +WRT 235-01;Writing Children's Literature;3;1;MTH;11:30AM-12:45PM;Tanya Stone; 1/16 - 5/03;ENG-112 OR COR-125 O... more;MIC 305/306; +WRT 250-01;Book Publishing/Editor's Role;3;4;TF;8:30AM-9:45AM;Rebecca Holt; 1/16 - 5/03;Complete WRT-120 and... more;CCM 444; +WRT 324-51;Advanced Poetry Workshop;3;1;M;4PM-6:45PM;James Ellefson; 1/16 - 5/03;WRT-220;CCM 444; +WRT 325-01;Advanced Fiction Workshop;3;7;MTH;2:30PM-3:45PM;Rachel Carter; 1/16 - 5/03;WRT-220 or permissio... more;JOYC 103; +WRT 337-01;Creative Non-Fiction, Advanced;3;8;W;12:15PM-3PM;Sheila Liming; 1/16 - 5/03;WRT-137 and 57 compl... more;CCM 442; +WRT 346-51;Publishing in 21st Century;3;5;M;4PM-6:45PM;Tanya Stone; 1/16 - 5/03;60 completed credits;CCM 424; +WRT 347-01;Transmedia Storytelling;3;0;TF;1PM-2:15PM;Sheila Liming; 1/16 - 5/03;Complete either COM-... more;CCM 444; +WRT 350-51;Reading and Writing in Genre;3;0;W;5:30PM-8:15PM;William Stratton; 1/16 - 5/03;Complete WRT-120 and... more;CCM 442; + diff --git a/automation-sys320/week15/IOC.txt b/automation-sys320/week15/IOC.txt new file mode 100644 index 0000000..f1acb69 --- /dev/null +++ b/automation-sys320/week15/IOC.txt @@ -0,0 +1,6 @@ +etc/passwd +cmd= +/bin/bash +/bin/sh +1=1# +1=1-- diff --git a/automation-sys320/week15/access.log b/automation-sys320/week15/access.log new file mode 100644 index 0000000..a948873 --- /dev/null +++ b/automation-sys320/week15/access.log @@ -0,0 +1,20 @@ +10.0.17.5 - - [04/Mar/2024:13:28:46 -0500] "GET /index.html HTTP/1.1" 404 295 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36" +10.0.17.5 - - [04/Mar/2024:13:29:21 -0500] "GET /index.html HTTP/1.1" 200 758 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36" +10.0.17.5 - - [04/Mar/2024:14:42:42 -0500] "GET /index.php HTTP/1.1" 404 295 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36" +10.0.17.5 - - [04/Mar/2024:14:43:07 -0500] "GET /index.php HTTP/1.1" 200 758 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36" +10.0.17.5 - - [04/Mar/2024:14:43:21 -0500] "GET /index.php?a=1&b=2 HTTP/1.1" 200 758 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36" +10.0.17.5 - - [04/Mar/2024:14:43:50 -0500] "GET /index.php?cmd=etc/passwd HTTP/1.1" 200 758 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36" +10.0.17.5 - - [04/Mar/2024:14:44:19 -0500] "GET /index.php?cmd=cat+etc/passwd HTTP/1.1" 200 758 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36" +10.0.17.5 - - [04/Mar/2024:14:44:52 -0500] "GET /index.php?cmd=/bing/bash+myscript.bash HTTP/1.1" 200 758 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36" +10.0.17.5 - - [04/Mar/2024:14:45:01 -0500] "GET /index.php?cmd=/bin/bash+myscript.bash HTTP/1.1" 200 758 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36" +10.0.17.5 - - [04/Mar/2024:14:45:19 -0500] "GET /index.php?cmd=/bin/sh+simplebackdoor.bash HTTP/1.1" 200 758 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36" +10.0.17.5 - - [04/Mar/2024:14:45:31 -0500] "GET /index.php?/bin/sh+simplebackdoor.bash HTTP/1.1" 200 758 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36" +10.0.17.5 - - [04/Mar/2024:14:46:03 -0500] "GET /index.php?a=1+OR+1=1-- HTTP/1.1" 200 758 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36" +10.0.17.5 - - [04/Mar/2024:14:46:12 -0500] "GET /index.php?a=1+OR+1=1- HTTP/1.1" 200 758 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36" +10.0.17.5 - - [04/Mar/2024:14:46:27 -0500] "GET /index.php?a=1+OR+1=1 HTTP/1.1" 200 758 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36" +10.0.17.5 - - [04/Mar/2024:14:46:47 -0500] "GET /index.php?word=Hello+World HTTP/1.1" 200 758 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36" +10.0.17.6 - - [04/Mar/2024:14:48:39 -0500] "GET / HTTP/1.1" 200 758 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:123.0) Gecko/20100101 Firefox/123.0" +10.0.17.6 - - [04/Mar/2024:14:48:40 -0500] "GET /favicon.ico HTTP/1.1" 404 295 "http://10.0.17.5/" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:123.0) Gecko/20100101 Firefox/123.0" +10.0.17.6 - - [04/Mar/2024:14:48:50 -0500] "GET /index.html HTTP/1.1" 200 758 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:123.0) Gecko/20100101 Firefox/123.0" +10.0.17.6 - - [04/Mar/2024:14:49:44 -0500] "GET /index.html?command=/bin/bash/+reverseshell.bash HTTP/1.1" 200 758 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:123.0) Gecko/20100101 Firefox/123.0" +10.0.17.6 - - [04/Mar/2024:14:50:24 -0500] "GET /index.html?command=/bin/bash/+midtermcheatdetector.bash HTTP/1.1" 200 758 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:123.0) Gecko/20100101 Firefox/123.0" diff --git a/automation-sys320/week15/finalC1.bash b/automation-sys320/week15/finalC1.bash new file mode 100644 index 0000000..855e1de --- /dev/null +++ b/automation-sys320/week15/finalC1.bash @@ -0,0 +1,21 @@ +#! /bin/bash + +# This is the link we will scrape +link="10.0.17.6/IOC.html" + +# get it with curl and tell curl not to give errors +fullPage=$(curl -sL "$link") + +# Utilizing xmlstarlet tool to extract table from the page +toolOutput=$(echo "$fullPage" | \ +xmlstarlet format --html --recover 2>/dev/null | \ +xmlstarlet select -n --template --copy-of \ +"//html//body//table//tr//td[1]") + +# Processing HTML with sed +echo "$toolOutput" | sed -e 's/]*>//g' | sed -e 's/<\/td>/;/g' | \ +tr ';' '\n' | sed '/^$/d' > IOC.txt + + + + diff --git a/automation-sys320/week15/finalC2.bash b/automation-sys320/week15/finalC2.bash new file mode 100644 index 0000000..7d01b8d --- /dev/null +++ b/automation-sys320/week15/finalC2.bash @@ -0,0 +1,4 @@ +#!/bin/bash + +cat access.log | cut -d' ' -f1,4,7 | tr -d '[' | \ +egrep -i -f IOC.txt > report.txt diff --git a/automation-sys320/week15/finalC3.bash b/automation-sys320/week15/finalC3.bash new file mode 100644 index 0000000..50bb3db --- /dev/null +++ b/automation-sys320/week15/finalC3.bash @@ -0,0 +1,16 @@ +#!/bin/bash +# turn report.txt into an html report + +echo -e "\n\n\t\n\n\n

Access logs with IOC indicators:

\n" > report.html + +cat report.txt | while read -r line; do + echo -e "\t\n" >> report.html + for element in $line; do + echo -e "\t\t" >> report.html + done + echo -e "\t" >> report.html +done + +echo -e "
$element
\n\n" >> report.html + +cp report.html /var/www/html/report.html diff --git a/automation-sys320/week15/report.html b/automation-sys320/week15/report.html new file mode 100644 index 0000000..e586d95 --- /dev/null +++ b/automation-sys320/week15/report.html @@ -0,0 +1,66 @@ + + + + + +

Access logs with IOC indicators:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
10.0.17.504/Mar/2024:14:43:50/index.php?cmd=etc/passwd
10.0.17.504/Mar/2024:14:44:19/index.php?cmd=cat+etc/passwd
10.0.17.504/Mar/2024:14:44:52/index.php?cmd=/bing/bash+myscript.bash
10.0.17.504/Mar/2024:14:45:01/index.php?cmd=/bin/bash+myscript.bash
10.0.17.504/Mar/2024:14:45:19/index.php?cmd=/bin/sh+simplebackdoor.bash
10.0.17.504/Mar/2024:14:45:31/index.php?/bin/sh+simplebackdoor.bash
10.0.17.504/Mar/2024:14:46:03/index.php?a=1+OR+1=1--
10.0.17.604/Mar/2024:14:49:44/index.html?command=/bin/bash/+reverseshell.bash
10.0.17.604/Mar/2024:14:50:24/index.html?command=/bin/bash/+midtermcheatdetector.bash
+ + diff --git a/automation-sys320/week15/report.txt b/automation-sys320/week15/report.txt new file mode 100644 index 0000000..c15ed9c --- /dev/null +++ b/automation-sys320/week15/report.txt @@ -0,0 +1,9 @@ +10.0.17.5 04/Mar/2024:14:43:50 /index.php?cmd=etc/passwd +10.0.17.5 04/Mar/2024:14:44:19 /index.php?cmd=cat+etc/passwd +10.0.17.5 04/Mar/2024:14:44:52 /index.php?cmd=/bing/bash+myscript.bash +10.0.17.5 04/Mar/2024:14:45:01 /index.php?cmd=/bin/bash+myscript.bash +10.0.17.5 04/Mar/2024:14:45:19 /index.php?cmd=/bin/sh+simplebackdoor.bash +10.0.17.5 04/Mar/2024:14:45:31 /index.php?/bin/sh+simplebackdoor.bash +10.0.17.5 04/Mar/2024:14:46:03 /index.php?a=1+OR+1=1-- +10.0.17.6 04/Mar/2024:14:49:44 /index.html?command=/bin/bash/+reverseshell.bash +10.0.17.6 04/Mar/2024:14:50:24 /index.html?command=/bin/bash/+midtermcheatdetector.bash diff --git a/db-security-sec300/README.md b/db-security-sec300/README.md new file mode 100644 index 0000000..c8bb1d3 --- /dev/null +++ b/db-security-sec300/README.md @@ -0,0 +1,9 @@ +# Database Security +Fall 2024 - 1 credit course + +- [Week1](https://git.charlotte.sh/lotte/ChamplainTechJournals/src/branch/main/db-security-sec300/week1.md): mySQL +- [Week2](https://git.charlotte.sh/lotte/ChamplainTechJournals/src/branch/main/db-security-sec300/week2.md): DB-Webserver connection +- [Week3](https://git.charlotte.sh/lotte/ChamplainTechJournals/src/branch/main/db-security-sec300/week3.md): filtering at database +- [Week4](https://git.charlotte.sh/lotte/ChamplainTechJournals/src/branch/main/db-security-sec300/week4.md): log analysis +- [Week5](https://git.charlotte.sh/lotte/ChamplainTechJournals/src/branch/main/db-security-sec300/week5.md): emailing logs + diff --git a/db-security-sec300/week1.md b/db-security-sec300/week1.md new file mode 100644 index 0000000..615b4b1 --- /dev/null +++ b/db-security-sec300/week1.md @@ -0,0 +1,55 @@ +# Week1 + +Summary: Set up mysql, basic queries + +### Install mysql-server: + +* `sudo apt-get install mysql-server` + +![](https://lh7-rt.googleusercontent.com/docsz/AD_4nXdPFliHfcxJyOK9EcpTFg086E21yXVxgJZz5gXCXbOkiw8qH8kulFJy4MyjKOoJomBoFtsGkVgGWAMp5z3DMis_Hda2otT6KUCnSJhrDi6sZzykgYYmX3bsgqhLme2bggCzbXi1?key=aDi9OQh-ufWQEzuXd3URpoOQ) + +* change bind address via `/etc/mysql/mysql.conf.d/mysqld.cnf`![](https://lh7-rt.googleusercontent.com/docsz/AD_4nXeGjZtbVFOHn9cjlkkew7w_A0YNNaGV5XepJ15r091W4LaWaj51D4BBdPFjT5N2TV6hhuMhYUaBPsrtPg9NfMVwhWyAK18DrNFUqG3HYBcgamPCs45LGOFHl2zGWdaO9t0-fLY?key=aDi9OQh-ufWQEzuXd3URpoOQ) +* remember! `sudo systemctl restart mysql` +* default password is found in `/etc/mysql/debian.cnf` +* first login: `sudo mysql -u root -p` +* show current users/DBs: `USE mysql;`, `SELECT User, Host FROM mysql.user;`, `SHOW DATABASES;` +* create registration DB: `CREATE DATABASE registration;` +* `USE registration;` +* create requests table: + +``` +CREATE TABLE requests( +id INT unsigned NOT NULL AUTO_INCREMENT, +fname VARCHAR(50) NOT NULL, +email VARCHAR(50) NOT NULL, +rdate DATE NOT NULL, +uid VARCHAR(15) NOT NULL, +PRIMARY KEY (id) +); +``` + +* show table: `DESCRIBE requests;` + +![](https://lh7-rt.googleusercontent.com/docsz/AD_4nXdlvLE49RvjHQiyucG79dyVIohHu3qnyrDPOEFOOvUJEhIb8bxhtCT7ba8SkgWT-nVApwqg22IDQ5w8hx1TNCiSlhA9HMIgE_4mMvw8Ji-lz7CKvN33oG-ZdxW6NzVwJk_Vkcn8?key=aDi9OQh-ufWQEzuXd3URpoOQ) + +* add data to table: `INSERT INTO requests (fname, email, rdate, uid) VALUES ( 'dummy', 'dummy@dummy.edu', '2024-11-12', 'nsk31fhenfJF024');`![](https://lh7-rt.googleusercontent.com/docsz/AD_4nXc_GuGlbOQitjuCJbrgURaAGcqcndwuWmBpjxnpkbHUQ6x58zJtF2Q_xA9PyCKEbs9aOsatZAL6u80-fQHTBI1Eca5HpWurp8hSwfLD5sL_JoQNfaYJ8u8OwWmcbtxMDlZ2yFbI?key=aDi9OQh-ufWQEzuXd3URpoOQ) + +### HW + +![](<../assets/63700441181267143731.png>) + +1: Write an SQL query that displays name and birth of cats whose names are Siggy + +![](https://lh7-rt.googleusercontent.com/docsz/AD_4nXf_wUTuyRVkT6DUoJCL4ILqzz23ZzZlHl2PuKfbdpGRgFYAfWd2QKuyAZjJ2WRowefQSZA1Y4DIO-6YXcNZ7JyRs9LiG-F6bcGumW6MjZnod6iRY9h0Cl16AcQxEeceub1l2OZQ?key=aDi9OQh-ufWQEzuXd3URpoOQ) + +2: Write an SQL query that displays name and birth of cats whose owners names are starting with the letter 'F' + +![](https://lh7-rt.googleusercontent.com/docsz/AD_4nXdBbRLxx7MylSUPgkJdsIZV-g6qP4f6CCI1TmryLwcWpN8bpYK62Lda1PYeY6Mfz0gMeNFHsoheL27e9mhPo0iEhE4TjWwHWPx5F9yy_UaA-cvFWJhPmgV8q_OOQIU7IHTM8rJL?key=aDi9OQh-ufWQEzuXd3URpoOQ) + +3: Write an SQL query that displays the cat names, their owners names, and the birth of cats in single table for cats born in year 2020 + +![](https://lh7-rt.googleusercontent.com/docsz/AD_4nXe3LtKLAV8a8zVOgzyyKGdrXc0o7Vk60s4uTiFcImqlwAHbJRJNtDiyFZ_i8cmcmQtHPau2nJAjliZ73SJdKsW1vllJlzNDpTFBLeHtwPr086xFKktPgObUXKD5kOuHT-XijDYP?key=aDi9OQh-ufWQEzuXd3URpoOQ) + +4: Write an SQL query that displays names of owners who has no cats + +![](https://lh7-rt.googleusercontent.com/docsz/AD_4nXdJo5G58de6UKRTEqe56CNrodFTDxlIVWyLP0zgLAtt0AEwW8AhsGDY1-gqdlgE9xJIrva-7lhBWypYgz6-IVrlj4KFDD3h3q2NNex4gInncKzer2Khs_2IUpZj-iVGj1dRX5dd?key=aDi9OQh-ufWQEzuXd3URpoOQ) diff --git a/db-security-sec300/week2.md b/db-security-sec300/week2.md new file mode 100644 index 0000000..33ce1d8 --- /dev/null +++ b/db-security-sec300/week2.md @@ -0,0 +1,41 @@ +# Week2 + +## DB Webserver Connection + +* create user for remote access: + +![](<../assets/92898586767705871114.png>) + +* allow connections through firewall: `sudo ufw allow from 0.0.0.0 to 0.0.0.0 port 3306 proto tcp` +* get python dependencies: `sudo apt update && sudo apt install python3 python3-pip python3-venv` +* `cd /home/champuser/proj/` +* create virtual environment: `python3 -m venv .venv` activate: `. .venv/bin/activate` + +install flask: `pip install flask` + +Create directory for Flask: `mkdir Flask, cd Flask` + +dependencies `pip install Flask-MySQLdb pip install flask-mysql pip install cryptography` + +![](<../assets/03636611901023297692.png>) + +![](<../assets/72766234477222890914.png>) + +![](<../assets/19930188638651808078.png>) + +![](<../assets/33901315023577898721.png>) + +if localhost doesn't work, change bind-address in /etc/mysql/mysql.conf.d/mysqld.cnf + +## Filter from application + +* add form action +![](../assets/formaction.png) + +* add python form processing + + ![](<../assets/62052853300074043448.png>) + +## for pets db + +![](<../assets/53438651249532045143.png>) diff --git a/db-security-sec300/week3.md b/db-security-sec300/week3.md new file mode 100644 index 0000000..3d93947 --- /dev/null +++ b/db-security-sec300/week3.md @@ -0,0 +1,12 @@ +# Week3 +Filtering at the Database + + +- Create a trigger that will replace numbers entered to the cats name with the character 'X'. +![image](../assets/1ae0ed12-ac5c-4a8a-bb70-cbfbe1b28a3a.png) + +- Alter the table cats to add a CHECK that will not allow any cat birthday after 2024-11-23. +![image](../assets/fd5cfed4-9f89-46ea-82e9-e5f8f593a8c2.png) + +- Add another CHECK into cats that restricts the cat's name to 12 characters. +![image](../assets/e7adaa35-9aaa-4f0c-8a93-4f4ded361027.png) diff --git a/db-security-sec300/week4.md b/db-security-sec300/week4.md new file mode 100644 index 0000000..f64301e --- /dev/null +++ b/db-security-sec300/week4.md @@ -0,0 +1,17 @@ +# Week4 +Log analysis + +- `sudo nano /etc/mysql/mysql.conf.d/mysqld.cnf` + +![image](../assets/8c9e506d-5da1-4907-8773-2ef2dc7cd53b.png) + + +- Display failed connect logs, display only date, time, and user +``` +cat /var/log/mysql/query.log | awk -F"[[:space:]T]+" '/Access denied/ {print $1,$2,$9}' +``` + +- Display successful connect logs, display only date, time, and user +``` +cat /var/log/mysql/query.log | awk -F"[[:space:]T]+" '/Connect/ {print $1,$2,$5}' | grep -v 'Access' +``` diff --git a/db-security-sec300/week5.md b/db-security-sec300/week5.md new file mode 100644 index 0000000..d02b1c9 --- /dev/null +++ b/db-security-sec300/week5.md @@ -0,0 +1,37 @@ +# Week5 +Emailing failed login attempts + +- create App password at: https://security.google.com/settings/security/apppasswordsLinks to an external site. +- install ssmtp + - `sudo apt-get update && sudo apt-get install ssmtp` + +- edit `/etc/ssmtp/ssmtp.conf` +``` +root=charlotte.croce@mymail,champlain.edu +mailhub=smtp.gmail.com:587 +AuthUser=charlotte.croce@mymail.champlain.edu +AuthPass=YourAuthPass +UseSTARTTLS=Yes +``` + + +- Testing email functionality +``` +echo "To: charlotte.croce@mymail,champlain.edu" > emailform.txt +echo "Subject: Database Incident" >> emailform.txt +echo "Incident of Database" >> emailform.txt +cat emailform.txt | ssmtp charlotte.croce@mymail,champlain.edu +``` + +- Script to send email with failed login attempts + +![image](../assets/9587f614-c944-4943-9d33-aedb0e477008.png) + +crontab +- add permissions so crontab can execute the script + - `chmod +x dbsec.bash` +- `crontab -l` : list scheduled tasks +- `crontab -e` : edit scheduled tasks +- run the script every day at 3:35pm + - `35 15 * * * /bin/bash -c "/root/dbsec.bash"` + diff --git a/net-sec-controls-sec350/README.md b/net-sec-controls-sec350/README.md new file mode 100644 index 0000000..e7c85f2 --- /dev/null +++ b/net-sec-controls-sec350/README.md @@ -0,0 +1,24 @@ +# Network Security Controls + +| Machine | IP Address | Default Gateway | DNS Server | Network | Description | +|----------|------------|----------------|------------|-----------|----------| +| [fw01](machines/FW01.md) | eth0: 10.0.17.151/24
eth1: 172.16.50.2/29
eth2: 172.16.150.2/24 | 10.0.17.2 | 10.0.17.2 | WAN/DMZ/LAN | VyOS router for all networks | +| [edge01](machines/EDGE01.md) | eth0: 10.0.17.151/24
eth1: 172.16.50.2/29
eth2: 172.16.150.2/24 | 10.0.17.2 | 10.0.17.2 | WAN/DMZ/LAN | Assessment VyOS router | +| [fw-mgmt](machines/FW-MGMT.md) | eth0: 172.16.150.3/24
eth1: 172.16.200.2/28 | 172.16.150.2 | 172.16.150.2 | LAN/MGMT | VyOS for LAN/MGMT | +| [web01](machines/WEB01.md) | 172.16.50.3/29 | 172.16.50.2 | 172.16.50.2 | DMZ | CentOS Apache server | +| [nginx01](machines/NGINX01.md) | 172.16.50.3/29 | 172.16.50.2 | 172.16.50.2 | DMZ | Ubuntu NGINX server | +| [log01](machines/LOG01.md) | 172.16.50.5/29 | 172.16.50.2 | 172.16.50.2 | DMZ | CentOS log server | +| [jump](machines/LOG01.md#recommissioned-as-jump-server) | 172.16.50.4/29 | 172.16.50.2 | 172.16.50.2 | DMZ | SSH jump host | +| [wazuh](machines/WAZUH.md) | 172.16.200.10/28 | 172.16.200.2 | 172.16.200.2 | MGMT | Wazuh SIEM server | +| [mgmt01](machines/MGMT01.md) | 172.16.150.10/24 | 172.16.150.2 | 172.16.150.2 | LAN | Ubuntu admin station | +| [mgmt02](machines/MGMT02.md) | 172.16.200.11/28 | 172.16.200.2 | 172.16.200.2 | MGMT | Windows admin server | +| [wks01](machines/WKS01.md) | 172.16.150.50/24 | 172.16.150.2 | 172.16.150.2 | LAN | Windows workstation | +| [rw01](machines/RW01.md) | 10.0.17.51/24 | 10.0.17.2 | 10.0.17.2 | WAN | Ubuntu road warrior | +| [traveler](machines/TRAVELER.md) | 10.0.17.51/24 | 10.0.17.2 | 10.0.17.2 | WAN | Windows road warrior | +| [dhcp01](machines/DHCP01.md) | 172.16.150.151/24 | 172.16.150.2 | 172.16.150.2 | LAN | Ubuntu DHCP server | + +*Note: fw01 was replaced by edge01, web01 was replaced by nginx01, log01 was repurposed as jump, and rw01 was replaced by traveler* + +## Network Diagram - Before Midterm +![Diagram before midterm](https://git.charlotte.sh/lotte/ChamplainTechJournals/src/branch/main/net-sec-controls-sec350/diagrams/SEC350_network-diagram-beforemidterm.drawio.png?raw=true "Network Diagram") + diff --git a/net-sec-controls-sec350/configs/edge02/edge02.config.assessment.txt b/net-sec-controls-sec350/configs/edge02/edge02.config.assessment.txt new file mode 100644 index 0000000..109ddfe --- /dev/null +++ b/net-sec-controls-sec350/configs/edge02/edge02.config.assessment.txt @@ -0,0 +1,103 @@ +set firewall name DMZ-to-LAN default-action 'drop' +set firewall name DMZ-to-LAN enable-default-log +set firewall name DMZ-to-LAN rule 1 action 'accept' +set firewall name DMZ-to-LAN rule 1 state established 'enable' +set firewall name DMZ-to-LAN rule 10 action 'accept' +set firewall name DMZ-to-LAN rule 10 description 'wazuh agent communication with server' +set firewall name DMZ-to-LAN rule 10 destination address '172.16.200.10' +set firewall name DMZ-to-LAN rule 10 destination port '1514,1515' +set firewall name DMZ-to-LAN rule 10 protocol 'tcp' +set firewall name DMZ-to-WAN default-action 'drop' +set firewall name DMZ-to-WAN enable-default-log +set firewall name DMZ-to-WAN rule 1 action 'accept' +set firewall name DMZ-to-WAN rule 1 state established 'enable' +set firewall name DMZ-to-WAN rule 10 action 'accept' +set firewall name DMZ-to-WAN rule 10 description 'NGINX->WAN' +set firewall name DMZ-to-WAN rule 10 source address '172.16.50.3' +set firewall name LAN-to-DMZ default-action 'drop' +set firewall name LAN-to-DMZ enable-default-log +set firewall name LAN-to-DMZ rule 1 action 'accept' +set firewall name LAN-to-DMZ rule 1 state established 'enable' +set firewall name LAN-to-DMZ rule 10 action 'accept' +set firewall name LAN-to-DMZ rule 10 description 'Allow HTTP from LAN to DMZ' +set firewall name LAN-to-DMZ rule 10 destination address '172.16.50.3' +set firewall name LAN-to-DMZ rule 10 destination port '80' +set firewall name LAN-to-DMZ rule 10 protocol 'tcp' +set firewall name LAN-to-DMZ rule 20 action 'accept' +set firewall name LAN-to-DMZ rule 20 description 'Allow SSH from MGMT-01 to DMZ' +set firewall name LAN-to-DMZ rule 20 destination port '22' +set firewall name LAN-to-DMZ rule 20 protocol 'tcp' +set firewall name LAN-to-DMZ rule 20 source address '172.16.150.10' +set firewall name LAN-to-WAN default-action 'drop' +set firewall name LAN-to-WAN enable-default-log +set firewall name LAN-to-WAN rule 1 action 'accept' +set firewall name WAN-to-DMZ default-action 'drop' +set firewall name WAN-to-DMZ enable-default-log +set firewall name WAN-to-DMZ rule 1 action 'accept' +set firewall name WAN-to-DMZ rule 1 state established 'enable' +set firewall name WAN-to-DMZ rule 10 action 'accept' +set firewall name WAN-to-DMZ rule 10 description 'allow HTTP from WAN to DMZ' +set firewall name WAN-to-DMZ rule 10 destination address '172.16.50.3' +set firewall name WAN-to-DMZ rule 10 destination port '80' +set firewall name WAN-to-DMZ rule 10 protocol 'tcp' +set firewall name WAN-to-DMZ rule 20 action 'accept' +set firewall name WAN-to-DMZ rule 20 description 'SSH to JUMP' +set firewall name WAN-to-DMZ rule 20 destination address '172.16.50.4' +set firewall name WAN-to-DMZ rule 20 destination port '22' +set firewall name WAN-to-DMZ rule 20 protocol 'tcp' +set firewall name WAN-to-LAN default-action 'drop' +set firewall name WAN-to-LAN enable-default-log +set firewall name WAN-to-LAN rule 1 action 'accept' +set firewall name WAN-to-LAN rule 1 state established 'enable' +set interfaces ethernet eth0 address '10.0.17.151/24' +set interfaces ethernet eth0 description 'SEC350-WAN' +set interfaces ethernet eth1 address '172.16.50.2/29' +set interfaces ethernet eth1 description 'CHARLOTTE-DMZ' +set interfaces ethernet eth2 address '172.16.150.2/24' +set interfaces ethernet eth2 description 'CHARLOTTE-LAN' +set nat destination rule 10 description 'HTTP->NGINX01' +set nat destination rule 10 destination port '80' +set nat destination rule 10 inbound-interface 'eth0' +set nat destination rule 10 protocol 'tcp' +set nat destination rule 10 translation address '172.16.50.3' +set nat destination rule 20 description 'SSH->JUMP' +set nat destination rule 20 destination port '22' +set nat destination rule 20 inbound-interface 'eth0' +set nat destination rule 20 protocol 'tcp' +set nat destination rule 20 translation address '172.16.50.4' +set nat source rule 10 description 'NAT FROM DMZ to WAN' +set nat source rule 10 outbound-interface 'eth0' +set nat source rule 10 source address '172.16.50.0/29' +set nat source rule 10 translation address 'masquerade' +set nat source rule 20 description 'NAT FROM LAN to WAN' +set nat source rule 20 outbound-interface 'eth0' +set nat source rule 20 source address '172.16.150.0/24' +set nat source rule 20 translation address 'masquerade' +set nat source rule 30 description 'NAT FROM MGMT to WAN' +set nat source rule 30 outbound-interface 'eth0' +set nat source rule 30 source address '172.16.200.0/28' +set nat source rule 30 translation address 'masquerade' +set protocols rip interface eth2 +set protocols rip network '172.16.50.0/29' +set protocols static route 0.0.0.0/0 next-hop 10.0.17.2 +set service dhcp-relay interface 'eth0' +set service dhcp-relay interface 'eth2' +set service dhcp-relay server '172.16.150.151' +set service dns forwarding allow-from '172.16.150.0/24' +set service dns forwarding allow-from '172.16.50.0/29' +set service dns forwarding listen-address '172.16.150.2' +set service dns forwarding listen-address '172.16.50.2' +set service dns forwarding system +set service ssh listen-address '0.0.0.0' +set service ssh listen-address '172.16.150.2' +set system host-name 'edge02-charlotte' +set system name-server '10.0.17.2' +set zone-policy zone DMZ from LAN firewall name 'LAN-to-DMZ' +set zone-policy zone DMZ from WAN firewall name 'WAN-to-DMZ' +set zone-policy zone DMZ interface 'eth1' +set zone-policy zone LAN from DMZ firewall name 'DMZ-to-LAN' +set zone-policy zone LAN from WAN firewall name 'WAN-to-LAN' +set zone-policy zone LAN interface 'eth2' +set zone-policy zone WAN from DMZ firewall name 'DMZ-to-WAN' +set zone-policy zone WAN from LAN firewall name 'LAN-to-WAN' +set zone-policy zone WAN interface 'eth0' \ No newline at end of file diff --git a/net-sec-controls-sec350/configs/fw-mgmt/fw-mgmt.config.week03.txt b/net-sec-controls-sec350/configs/fw-mgmt/fw-mgmt.config.week03.txt new file mode 100644 index 0000000..6fd9351 --- /dev/null +++ b/net-sec-controls-sec350/configs/fw-mgmt/fw-mgmt.config.week03.txt @@ -0,0 +1,13 @@ +set interfaces ethernet eth0 address '172.16.150.3/24' +set interfaces ethernet eth0 description 'LAN' +set interfaces ethernet eth1 address '172.16.200.2/28' +set interfaces ethernet eth1 description 'MGMT' +set protocols rip interface eth0 +set protocols rip network '172.16.200.0/28' +set protocols static route 0.0.0.0/0 next-hop 172.16.150.2 +set service dns forwarding allow-from '172.16.200.0/28' +set service dns forwarding listen-address '172.16.200.2' +set service dns forwarding system +set service ssh listen-address '0.0.0.0' +set system host-name 'fw-mgmt-charlotte' +set system name-server '172.16.150.2' diff --git a/net-sec-controls-sec350/configs/fw-mgmt/fw-mgmt.config.week04.txt b/net-sec-controls-sec350/configs/fw-mgmt/fw-mgmt.config.week04.txt new file mode 100644 index 0000000..cd9d376 --- /dev/null +++ b/net-sec-controls-sec350/configs/fw-mgmt/fw-mgmt.config.week04.txt @@ -0,0 +1,49 @@ +set firewall name LAN-to-MGMT default-action 'drop' +set firewall name LAN-to-MGMT enable-default-log +set firewall name LAN-to-MGMT rule 1 action 'accept' +set firewall name LAN-to-MGMT rule 1 state established 'enable' +set firewall name LAN-to-MGMT rule 10 action 'accept' +set firewall name LAN-to-MGMT rule 10 description 'wazuh SSH access from MGMT-01' +set firewall name LAN-to-MGMT rule 10 destination address '172.16.200.10' +set firewall name LAN-to-MGMT rule 10 destination port '22' +set firewall name LAN-to-MGMT rule 10 protocol 'tcp' +set firewall name LAN-to-MGMT rule 10 source address '172.16.150.10' +set firewall name LAN-to-MGMT rule 20 action 'accept' +set firewall name LAN-to-MGMT rule 20 description 'wazuh HTTPS access from MGMT-01' +set firewall name LAN-to-MGMT rule 20 destination address '172.16.200.10' +set firewall name LAN-to-MGMT rule 20 destination port '443' +set firewall name LAN-to-MGMT rule 20 protocol 'tcp' +set firewall name LAN-to-MGMT rule 20 source address '172.16.150.10' +set firewall name LAN-to-MGMT rule 30 action 'accept' +set firewall name LAN-to-MGMT rule 30 description 'wazuh agent communication with server' +set firewall name LAN-to-MGMT rule 30 destination address '172.16.200.10' +set firewall name LAN-to-MGMT rule 30 destination port '1514,1515' +set firewall name LAN-to-MGMT rule 30 protocol 'tcp' +set firewall name MGMT-to-LAN default-action 'drop' +set firewall name MGMT-to-LAN enable-default-log +set firewall name MGMT-to-LAN rule 1 action 'accept' +set firewall name MGMT-to-LAN rule 1 state established 'enable' +set firewall name MGMT-to-LAN rule 10 action 'accept' +set firewall name MGMT-to-LAN rule 10 description 'allows MGMT to LAN' +set firewall name MGMT-to-LAN rule 10 destination address '172.16.150.0/24' +set firewall name MGMT-to-LAN rule 20 action 'accept' +set firewall name MGMT-to-LAN rule 20 description 'allows MGMT to DMZ' +set firewall name MGMT-to-LAN rule 20 destination address '172.16.50.0/29' +set interfaces ethernet eth0 address '172.16.150.3/24' +set interfaces ethernet eth0 description 'LAN' +set interfaces ethernet eth1 address '172.16.200.2/28' +set interfaces ethernet eth1 description 'MGMT' +set nat source +set protocols rip interface eth0 +set protocols rip network '172.16.200.0/28' +set protocols static route 0.0.0.0/0 next-hop 172.16.150.2 +set service dns forwarding allow-from '172.16.200.0/28' +set service dns forwarding listen-address '172.16.200.2' +set service dns forwarding system +set service ssh listen-address '0.0.0.0' +set system host-name 'fw-mgmt-charlotte' +set system name-server '172.16.150.2' +set zone-policy zone LAN from MGMT firewall name 'MGMT-to-LAN' +set zone-policy zone LAN interface 'eth0' +set zone-policy zone MGMT from LAN firewall name 'LAN-to-MGMT' +set zone-policy zone MGMT interface 'eth1' diff --git a/net-sec-controls-sec350/configs/fw01/fw01.config.week03.txt b/net-sec-controls-sec350/configs/fw01/fw01.config.week03.txt new file mode 100644 index 0000000..3a707ef --- /dev/null +++ b/net-sec-controls-sec350/configs/fw01/fw01.config.week03.txt @@ -0,0 +1,29 @@ +set interfaces ethernet eth0 address '10.0.17.151/24' +set interfaces ethernet eth0 description 'SEC350-WAN' +set interfaces ethernet eth1 address '172.16.50.2/29' +set interfaces ethernet eth1 description 'CHARLOTTE-DMZ' +set interfaces ethernet eth2 address '172.16.150.2/24' +set interfaces ethernet eth2 description 'CHARLOTTE-LAN' +set nat source rule 10 description 'NAT FROM DMZ to WAN' +set nat source rule 10 outbound-interface 'eth0' +set nat source rule 10 source address '172.16.50.0/29' +set nat source rule 10 translation address 'masquerade' +set nat source rule 20 description 'NAT from LAN to WAN' +set nat source rule 20 outbound-interface 'eth0' +set nat source rule 20 source address '172.16.150.0/24' +set nat source rule 20 translation address 'masquerade' +set nat source rule 30 description 'NAT from MGMT to LAN' +set nat source rule 30 outbound-interface 'eth0' +set nat source rule 30 source address '172.16.200.0/28' +set nat source rule 30 translation address 'masquerade' +set protocols rip interface eth2 +set protocols rip network '172.16.50.0/29' +set protocols static route 0.0.0.0/0 next-hop 10.0.17.2 +set service dns forwarding allow-from '172.16.50.0/29' +set service dns forwarding allow-from '172.16.150.0/24' +set service dns forwarding listen-address '172.16.50.2' +set service dns forwarding listen-address '172.16.150.2' +set service dns forwarding system +set service ssh listen-address '0.0.0.0' +set system host-name 'fw01-charlotte' +set system name-server '10.0.17.2' diff --git a/net-sec-controls-sec350/configs/fw01/fw01.config.week04.txt b/net-sec-controls-sec350/configs/fw01/fw01.config.week04.txt new file mode 100644 index 0000000..bf18615 --- /dev/null +++ b/net-sec-controls-sec350/configs/fw01/fw01.config.week04.txt @@ -0,0 +1,79 @@ +set firewall name DMZ-to-LAN default-action 'drop' +set firewall name DMZ-to-LAN enable-default-log +set firewall name DMZ-to-LAN rule 1 action 'accept' +set firewall name DMZ-to-LAN rule 1 state established 'enable' +set firewall name DMZ-to-LAN rule 10 action 'accept' +set firewall name DMZ-to-LAN rule 10 description 'wazuh agent communication with server' +set firewall name DMZ-to-LAN rule 10 destination address '172.16.200.10' +set firewall name DMZ-to-LAN rule 10 destination port '1514,1515' +set firewall name DMZ-to-LAN rule 10 protocol 'tcp' +set firewall name DMZ-to-WAN default-action 'drop' +set firewall name DMZ-to-WAN enable-default-log +set firewall name DMZ-to-WAN rule 1 action 'accept' +set firewall name DMZ-to-WAN rule 1 state established 'enable' +set firewall name LAN-to-DMZ default-action 'drop' +set firewall name LAN-to-DMZ enable-default-log +set firewall name LAN-to-DMZ rule 1 action 'accept' +set firewall name LAN-to-DMZ rule 1 state established 'enable' +set firewall name LAN-to-DMZ rule 10 action 'accept' +set firewall name LAN-to-DMZ rule 10 description 'Allow HTTP from LAN to DMZ' +set firewall name LAN-to-DMZ rule 10 destination address '172.16.50.3' +set firewall name LAN-to-DMZ rule 10 destination port '80' +set firewall name LAN-to-DMZ rule 10 protocol 'tcp' +set firewall name LAN-to-DMZ rule 20 action 'accept' +set firewall name LAN-to-DMZ rule 20 description 'Allow SSH from MGMT-01 to DMZ' +set firewall name LAN-to-DMZ rule 20 destination port '22' +set firewall name LAN-to-DMZ rule 20 protocol 'tcp' +set firewall name LAN-to-DMZ rule 20 source address '172.16.150.10' +set firewall name LAN-to-WAN default-action 'drop' +set firewall name LAN-to-WAN enable-default-log +set firewall name LAN-to-WAN rule 1 action 'accept' +set firewall name WAN-to-DMZ default-action 'drop' +set firewall name WAN-to-DMZ enable-default-log +set firewall name WAN-to-DMZ rule 10 action 'accept' +set firewall name WAN-to-DMZ rule 10 description 'allow HTTP from WAN to DMZ' +set firewall name WAN-to-DMZ rule 10 destination address '172.16.50.3' +set firewall name WAN-to-DMZ rule 10 destination port '80' +set firewall name WAN-to-DMZ rule 10 protocol 'tcp' +set firewall name WAN-to-LAN default-action 'drop' +set firewall name WAN-to-LAN enable-default-log +set firewall name WAN-to-LAN rule 1 action 'accept' +set firewall name WAN-to-LAN rule 1 state established 'enable' +set interfaces ethernet eth0 address '10.0.17.151/24' +set interfaces ethernet eth0 description 'SEC350-WAN' +set interfaces ethernet eth1 address '172.16.50.2/29' +set interfaces ethernet eth1 description 'CHARLOTTE-DMZ' +set interfaces ethernet eth2 address '172.16.150.2/24' +set interfaces ethernet eth2 description 'CHARLOTTE-LAN' +set nat source rule 10 description 'NAT FROM DMZ to WAN' +set nat source rule 10 outbound-interface 'eth0' +set nat source rule 10 source address '172.16.50.0/29' +set nat source rule 10 translation address 'masquerade' +set nat source rule 20 description 'NAT from LAN to WAN' +set nat source rule 20 outbound-interface 'eth0' +set nat source rule 20 source address '172.16.150.0/24' +set nat source rule 20 translation address 'masquerade' +set nat source rule 30 description 'NAT from MGMT to LAN' +set nat source rule 30 outbound-interface 'eth0' +set nat source rule 30 source address '172.16.200.0/28' +set nat source rule 30 translation address 'masquerade' +set protocols rip interface eth2 +set protocols rip network '172.16.50.0/29' +set protocols static route 0.0.0.0/0 next-hop 10.0.17.2 +set service dns forwarding allow-from '172.16.50.0/29' +set service dns forwarding allow-from '172.16.150.0/24' +set service dns forwarding listen-address '172.16.50.2' +set service dns forwarding listen-address '172.16.150.2' +set service dns forwarding system +set service ssh listen-address '0.0.0.0' +set system host-name 'fw01-charlotte' +set system name-server '10.0.17.2' +set zone-policy zone DMZ from LAN firewall name 'LAN-to-DMZ' +set zone-policy zone DMZ from WAN firewall name 'WAN-to-DMZ' +set zone-policy zone DMZ interface 'eth1' +set zone-policy zone LAN from DMZ firewall name 'DMZ-to-LAN' +set zone-policy zone LAN from WAN firewall name 'WAN-to-LAN' +set zone-policy zone LAN interface 'eth2' +set zone-policy zone WAN from DMZ firewall name 'DMZ-to-WAN' +set zone-policy zone WAN from LAN firewall name 'LAN-to-WAN' +set zone-policy zone WAN interface 'eth0' diff --git a/net-sec-controls-sec350/configs/fw01/fw01.config.week05.txt b/net-sec-controls-sec350/configs/fw01/fw01.config.week05.txt new file mode 100644 index 0000000..2df0deb --- /dev/null +++ b/net-sec-controls-sec350/configs/fw01/fw01.config.week05.txt @@ -0,0 +1,81 @@ +set firewall name DMZ-to-LAN default-action 'drop' +set firewall name DMZ-to-LAN enable-default-log +set firewall name DMZ-to-LAN rule 1 action 'accept' +set firewall name DMZ-to-LAN rule 1 state established 'enable' +set firewall name DMZ-to-LAN rule 10 action 'accept' +set firewall name DMZ-to-LAN rule 10 description 'wazuh agent communication with server' +set firewall name DMZ-to-LAN rule 10 destination address '172.16.200.10' +set firewall name DMZ-to-LAN rule 10 destination port '1514,1515' +set firewall name DMZ-to-LAN rule 10 protocol 'tcp' +set firewall name DMZ-to-WAN default-action 'drop' +set firewall name DMZ-to-WAN enable-default-log +set firewall name DMZ-to-WAN rule 1 action 'accept' +set firewall name DMZ-to-WAN rule 1 state established 'enable' +set firewall name LAN-to-DMZ default-action 'drop' +set firewall name LAN-to-DMZ enable-default-log +set firewall name LAN-to-DMZ rule 1 action 'accept' +set firewall name LAN-to-DMZ rule 1 state established 'enable' +set firewall name LAN-to-DMZ rule 10 action 'accept' +set firewall name LAN-to-DMZ rule 10 description 'Allow HTTP from LAN to DMZ' +set firewall name LAN-to-DMZ rule 10 destination address '172.16.50.3' +set firewall name LAN-to-DMZ rule 10 destination port '80' +set firewall name LAN-to-DMZ rule 10 protocol 'tcp' +set firewall name LAN-to-DMZ rule 20 action 'accept' +set firewall name LAN-to-DMZ rule 20 description 'Allow SSH from MGMT-01 to DMZ' +set firewall name LAN-to-DMZ rule 20 destination port '22' +set firewall name LAN-to-DMZ rule 20 protocol 'tcp' +set firewall name LAN-to-DMZ rule 20 source address '172.16.150.10' +set firewall name LAN-to-WAN default-action 'drop' +set firewall name LAN-to-WAN enable-default-log +set firewall name LAN-to-WAN rule 1 action 'accept' +set firewall name WAN-to-DMZ default-action 'drop' +set firewall name WAN-to-DMZ enable-default-log +set firewall name WAN-to-DMZ rule 1 action 'accept' +set firewall name WAN-to-DMZ rule 1 state established 'enable' +set firewall name WAN-to-DMZ rule 10 action 'accept' +set firewall name WAN-to-DMZ rule 10 description 'allow HTTP from WAN to DMZ' +set firewall name WAN-to-DMZ rule 10 destination address '172.16.50.3' +set firewall name WAN-to-DMZ rule 10 destination port '80' +set firewall name WAN-to-DMZ rule 10 protocol 'tcp' +set firewall name WAN-to-LAN default-action 'drop' +set firewall name WAN-to-LAN enable-default-log +set firewall name WAN-to-LAN rule 1 action 'accept' +set firewall name WAN-to-LAN rule 1 state established 'enable' +set interfaces ethernet eth0 address '10.0.17.151/24' +set interfaces ethernet eth0 description 'SEC350-WAN' +set interfaces ethernet eth1 address '172.16.50.2/29' +set interfaces ethernet eth1 description 'CHARLOTTE-DMZ' +set interfaces ethernet eth2 address '172.16.150.2/24' +set interfaces ethernet eth2 description 'CHARLOTTE-LAN' +set nat source rule 10 description 'NAT FROM DMZ to WAN' +set nat source rule 10 outbound-interface 'eth0' +set nat source rule 10 source address '172.16.50.0/29' +set nat source rule 10 translation address 'masquerade' +set nat source rule 20 description 'NAT from LAN to WAN' +set nat source rule 20 outbound-interface 'eth0' +set nat source rule 20 source address '172.16.150.0/24' +set nat source rule 20 translation address 'masquerade' +set nat source rule 30 description 'NAT from MGMT to LAN' +set nat source rule 30 outbound-interface 'eth0' +set nat source rule 30 source address '172.16.200.0/28' +set nat source rule 30 translation address 'masquerade' +set protocols rip interface eth2 +set protocols rip network '172.16.50.0/29' +set protocols static route 0.0.0.0/0 next-hop 10.0.17.2 +set service dns forwarding allow-from '172.16.50.0/29' +set service dns forwarding allow-from '172.16.150.0/24' +set service dns forwarding listen-address '172.16.50.2' +set service dns forwarding listen-address '172.16.150.2' +set service dns forwarding system +set service ssh listen-address '0.0.0.0' +set system host-name 'fw01-charlotte' +set system name-server '10.0.17.2' +set zone-policy zone DMZ from LAN firewall name 'LAN-to-DMZ' +set zone-policy zone DMZ from WAN firewall name 'WAN-to-DMZ' +set zone-policy zone DMZ interface 'eth1' +set zone-policy zone LAN from DMZ firewall name 'DMZ-to-LAN' +set zone-policy zone LAN from WAN firewall name 'WAN-to-LAN' +set zone-policy zone LAN interface 'eth2' +set zone-policy zone WAN from DMZ firewall name 'DMZ-to-WAN' +set zone-policy zone WAN from LAN firewall name 'LAN-to-WAN' +set zone-policy zone WAN interface 'eth0' diff --git a/net-sec-controls-sec350/diagrams/SEC350_network-diagram-aftermidterm.drawio b/net-sec-controls-sec350/diagrams/SEC350_network-diagram-aftermidterm.drawio new file mode 100644 index 0000000..fef52e5 --- /dev/null +++ b/net-sec-controls-sec350/diagrams/SEC350_network-diagram-aftermidterm.drawio @@ -0,0 +1,297 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/net-sec-controls-sec350/diagrams/SEC350_network-diagram-beforemidterm.drawio b/net-sec-controls-sec350/diagrams/SEC350_network-diagram-beforemidterm.drawio new file mode 100644 index 0000000..b37af0f --- /dev/null +++ b/net-sec-controls-sec350/diagrams/SEC350_network-diagram-beforemidterm.drawio @@ -0,0 +1,306 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/net-sec-controls-sec350/diagrams/SEC350_network-diagram-beforemidterm.drawio.png b/net-sec-controls-sec350/diagrams/SEC350_network-diagram-beforemidterm.drawio.png new file mode 100644 index 0000000..606d924 Binary files /dev/null and b/net-sec-controls-sec350/diagrams/SEC350_network-diagram-beforemidterm.drawio.png differ diff --git a/net-sec-controls-sec350/labs/week01/lab1.1-routing-and-dmz.md b/net-sec-controls-sec350/labs/week01/lab1.1-routing-and-dmz.md new file mode 100644 index 0000000..9f33a4b --- /dev/null +++ b/net-sec-controls-sec350/labs/week01/lab1.1-routing-and-dmz.md @@ -0,0 +1,121 @@ +# Lab 1.1, Routing and DMZ + +## Configuring rw01 +- changing the champuser password: `password123!` +- set hostname to `rw01-charlotte`([reference](https://git.charlotte.sh/lotte/ChamplainTechJournals/src/branch/main/sysadmin-i-sys255/lab03-linux.md#set-hostname)) +- add sudo user `charlotte:password123!` ([reference](https://git.charlotte.sh/lotte/ChamplainTechJournals/src/branch/main/sysadmin-i-sys255/lab03-linux.md#creating-privileged-user)) +- Make sure you have a static ip that matches the one in the IP assignments spreadsheet: use **nmtui**, set IP to `10.0.17.51/24` and gateway/DNS to `10.0.17.2` \ +![image](../../../assets/46252357-1387-45bd-a4ae-ede9e12417c9.png) + + +## fw01, gateway/router/firewall ([VyOS doc](https://git.charlotte.sh/lotte/ChamplainTechJournals/src/branch/main/net-sec-controls-sec350/vyos.md)) +![image](../../../assets/723c16dc-f130-4f61-9508-b0fe70adbca5.png) \ +default creds: `vyoz:Ch@mpla1n!22` + +### set hostname +``` +configure +set system host-name fw01-charlotte +commit +save +``` +Repeat exit until you get to a login prompt. Then you should see your new hostname, so go ahead and log in back to configure. + +### configure interfaces +``` +configure +set interfaces ethernet eth0 description SEC350-WAN +set interfaces ethernet eth1 description CHARLOTTE-DMZ +set interfaces ethernet eth2 description CHARLOTTE-LAN +set interfaces ethernet eth0 address 10.0.17.151/24 +set interfaces ethernet eth1 address 172.16.50.2/29 +set interfaces ethernet eth2 address 172.16.150.2/24 +commit +save +``` +![image](../../../assets/2a546cc0-a012-48b3-bfc8-3884334decfa.png) + +### configure gateway & DNS +``` +configure +set protocols static route 0.0.0.0/0 next-hop 10.0.17.2 +set system name-server 10.0.17.2 +commit +save +``` + +### Configuring NAT and DNS Forwarding for DMZ +``` +configure +set nat source rule 10 description "NAT FROM DMZ to WAN" +set nat source rule 10 outbound-interface eth0 +set nat source rule 10 source address 172.16.50.0/29 +set nat source rule 10 translation address masquerade +set service dns forwarding listen-address 172.16.50.2 +set service dns forwarding allow-from 172.16.50.0/29 +set service dns forwarding system +commit +save +``` +![image](../../../assets/2fe9dd01-e8e0-48c6-86a0-6f41fba39886.png) + + +## web01, web server +### basics +- Set adapter to DMZ: \ +![image](../../../assets/a2abea31-7eb8-486a-b563-3962d086ab44.png) \ +default creds: `root:Ch@mpl@1n!22` + +- set hostname to `web01-charlotte`([reference](https://git.charlotte.sh/lotte/ChamplainTechJournals/src/branch/main/sysadmin-i-sys255/lab03-linux.md#set-hostname)) +- add sudo user `charlotte:password123!` ([reference](https://git.charlotte.sh/lotte/ChamplainTechJournals/src/branch/main/sysadmin-i-sys255/lab03-linux.md#creating-privileged-user)) +- `nmtui` \ +![image](../../../assets/c69680f9-be75-4b5e-976b-cf6b508f6553.png) \ +![image](../../../assets/06fa4ee7-ce28-40d2-8193-3f84b03b41d1.png) + +### configure httpd +- install httpd ([reference](https://git.charlotte.sh/lotte/ChamplainTechJournals/src/branch/main/sysadmin-i-sys255/lab08-apache.md#install-httpd)) + + +### on rw01, testing web service +- any address in your DMZ should route via fw01’s WAN interface. We do this with a static route on rw01 +- anything addressed to the 172.16.50.0/29 network will go through the 10.0.17.151 router +``` +sudo ip route add 172.16.50.0/29 via 10.0.17.151 +sudo systemctl restart NetworkManager +traceroute 172.16.50.3 +``` + + +## log01, rsyslog server +log01 will be initially in the DMZ, later we will change this to a segmented network area +### basics +![image](../../../assets/b7112a43-e0e0-4d8c-af36-a7a925ccc1d8.png) +- set hostname to `log01-charlotte`([reference](https://git.charlotte.sh/lotte/ChamplainTechJournals/src/branch/main/sysadmin-i-sys255/lab03-linux.md#set-hostname)) +- add sudo user `charlotte:password123!` ([reference](https://git.charlotte.sh/lotte/ChamplainTechJournals/src/branch/main/sysadmin-i-sys255/lab03-linux.md#creating-privileged-user)) + + +### rsyslog setup +![image](../../../assets/4b9ac768-72f6-4ef4-92ed-5be231e63c7b.png) \ +![image](../../../assets/cd26c18f-74b8-481c-bc37-8c602f7f46c7.png) + + +allow UDP and TCP 514 for syslog traffic +``` +sudo firewall-cmd --add-port=514/tcp --permament +sudo firewall-cmd --add-port=514/udp --permament +sudo firewall-cmd --reload +``` +![image](../../../assets/62b95926-6b2a-42e2-a12f-610b1a3336b8.png) + +On log01, the `/etc/rsyslog.conf` file needs to be modified to receive syslog messages over ports 514 tcp and udp. Uncomment the appropriate lines (see below) and restart the rsyslog service. +![image](../../../assets/48994d9b-0f17-4626-ab9d-985d37c5e506.png) \ +![image](../../../assets/b7c9efbf-0819-4381-99f7-14826220bb8a.png) + +### on web01, configure log forwarding to log01 +- `sudo yum install rsyslog` +- Create the following file: `/etc/rsyslog.d/sec350.conf` and restart rsyslog on web01 +![image](../../../assets/143d58a5-5713-4425-b1d5-d8f9dcf63cf0.png) + +- monitor incoming logs on log01: `tail -f /var/log/messages` +- create test log on web01: `logger -t test TESTFROMWEB01TOLOG01` + diff --git a/net-sec-controls-sec350/labs/week01/setup_script.sh b/net-sec-controls-sec350/labs/week01/setup_script.sh new file mode 100644 index 0000000..d0fa789 --- /dev/null +++ b/net-sec-controls-sec350/labs/week01/setup_script.sh @@ -0,0 +1,65 @@ +#!/bin/bash +# script to streamline basic linux setup + + +function sethostname(){ + if [ -z "$1" ]; then # if no arg (using menu), prompt user + echo "current hostname: " $(hostname) + echo -n "new hostname ( to skip): " + read newhostname + if [ -z ${newhostname} ]; then + return 0 + fi + echo "...'hostnamectl set-hostname ${newhostname}'" + hostnamectl set-hostname ${newhostname} + else # if arg provided, set hostname to arg + hostnamectl set-hostname $1 + fi + echo "current hostname: " $(hostname) +} + +function addsudouser(){ + if [ -z $2 ]; then + echo -n "username: " + read username + echo -n "password: " + read password + echo "...adduser ${username}" + adduser ${username} + echo "...echo ${password} | passwd ${username} --stdin" + echo ${password} | passwd ${username} --stdin + echo "...'usermod -aG sudo ${username}" + usermod -aG sudo ${username} + fi +} + +# privilege check. this script has to be run as root (sudo) +user=$(whoami) +if [[ "$user" != "root" ]]; then + echo "please run as root. exiting..." + exit 0 +fi + +# interactive menu +while : +do + echo "PLease select an option:" + echo "[1] Set Hostname" + echo "[2] create user" + echo "[7] Quit" + echo -n "> " + read userInput + echo "" + + if [[ "$userInput" == "1" ]]; then + sethostname + + elif [[ "$userInput" == "2" ]]; then + addsudouser + + elif [[ "$userInput" == "7" ]]; then + echo "Exiting,,." + break + fi +done + diff --git a/net-sec-controls-sec350/labs/week02/Lab2.1-standardizing-time.md b/net-sec-controls-sec350/labs/week02/Lab2.1-standardizing-time.md new file mode 100644 index 0000000..019cca1 --- /dev/null +++ b/net-sec-controls-sec350/labs/week02/Lab2.1-standardizing-time.md @@ -0,0 +1,23 @@ +# Lab 2.1 Standardizing on Time +Time is not recorded consistently across all of our systems. You will note very quickly that none of your systems record the timezone within the syslog entry. Without this data it is very hard to develop a cohesive timeline for events that span multiple log sources and multiple time zones. We are going to fix this. + +Though the date is set for EST, the specific log entry that may or may not be forwarded to a log server has no indication of the timezone or the year. + +![image](../../../assets/9f753b28-fd3b-4854-b155-54bca96e239c.png) + +## rw01 - ubuntu +We fix this by commenting out a line (shown below) in RW01's main `/etc/rsyslog.conf` file. By default, rsyslog does not use high precision timestamps. Make sure to restart rsyslog on rw01 +![image](../../../assets/8ed3b550-988b-432c-895e-3f1e3acceb45.png) + +![image](../../../assets/aa578b16-2113-4af0-b7c7-ae18e52ad336.png) + + +## web01 & log01 - rocky +in `/etc/rsyslog.conf` +- add these lines: + - `$ActionFileDefaultTemplate RSYSLOG_SyslogProtocol23Format`---enables RFC 5424-style syslog format, which includes high-precision timestamps with timezone information. + - `template(name="BetterTiming" type="string" string="%timestamp:::date-rfc3339% %HOSTNAME% %syslogtag%%msg%\n")`---explicitly defines a custom template, including high-fidelity timestamps with timezone info + - add the suffix `;BetterTiming` to the loggging destination---enables the custom template on your logs + +![image](../../../assets/0331dde8-2028-445d-89e2-d55fb5b3cf45.png) +![image](../../../assets/742df745-1a26-4c6d-a082-d7edfa04fd2f.png) diff --git a/net-sec-controls-sec350/labs/week02/Lab2.2-syslog-organization.md b/net-sec-controls-sec350/labs/week02/Lab2.2-syslog-organization.md new file mode 100644 index 0000000..0e60b29 --- /dev/null +++ b/net-sec-controls-sec350/labs/week02/Lab2.2-syslog-organization.md @@ -0,0 +1,66 @@ +# Lab 2.2 - Syslog Organization on log01 + +## setup mgmt01 +- on LAN +- ip: 172.16.150.10 +- DG & DNS: 172.16.150.2 + +### configure fw01 with the LAN +#### NAT rules on fw01, to set NAT for LAN to WAN +``` +set nat source rule 20 description "NAT FROM LAN to WAN" +set nat source rule 20 outbound-interface eth0 +set nat source rule 20 source address 172.16.150.0/24 +set nat source rule 20 translation address masquerade +``` +#### DNS forwarding from LAN to WAN +``` +set service dns forwarding listen-address 172.16.150.2 +set service dns forwarding allow-from 172.16.150.0/24 +``` +mgmt01 should now be able to ping google.com + +### Install chrome remote desktop on mgmt01 +- open chrome +- sign in with school email and turn on sync +- go to remotedesktop.google.com, install the app if you want +- on main host (laptop, go to `https://g.co/crd/headless`), download and install the package: + - there might be dependency issues, this command worked on my computer: `sudo apt install libutempter0 xbase-clients xserver-xorg-video-dummy xvfb` + - `sudo dpkg -i google-chrome-stable_current_amd64` +- still on main host, click next and copy the command for the remote OS (in our case, debian) +- paste it in the remote terminal, and create a PIN +- at this point you should be able to access mgmt01 via chrome remote desktop, you might need to update CRD on mgmt01 first though, but we know how to do that ^ +- IMPORTANT: log out of the remote computer before attempting to connect + +## log organization on log01 +Having all of our remote logs stuffed into log01's /var/log/messages or /var/log/secure is not helpful. Remote logs should be segregated and ideally stored on reliable and redundant storage in a manner that supports dealing with discrete event types. We are going to store logs in a directory hierarchy in order to provide this organization. + +- re-comment the input modules from lab 1.1 +![image](../../../assets/a51c6beb-41a7-4885-a285-61885f073995.png) +- create a new config file call sec350.conf: +![image](../../../assets/c12ab0af-4ef2-4904-9ede-9d4d96a65122.png) +- copy that file to /etc/rsyslod.d/: `sudo cp sec350.conf /etc/rsyslog.d/` + +``` +This configuration file (03-sec350.conf) will dynamically create and name files based upon hostname, +date and process name. Input over udp 514 is associated with the RemoteDevice ruleset which in turn +uses the dynamic template configuration called “DynFile”. +``` +testing \ +![image](../../../assets/37f2c335-0611-42c9-962a-62a4681eeae5.png) +![image](../../../assets/3b863e99-1ae4-4d29-91cb-1a3b187aab5f.png) + +## web01: Logging Authorization Events +Modify the rsyslog client configuration on web01 so that authentication events are forwarded to our log server. the line `authpriv.* @172.16.50.5` will send all authpriv logs to the remote server(log01) +![image](../../../assets/59be1bd2-d915-4360-9595-f0d32d68e030.png) \ +after sshing from rw01>web01(with failed attempts), we can see this in the sshd.log file \ +![image](../../../assets/f45b745c-6aff-4cd6-86dd-0ddb13256267.png) + +## fw01: Logging Authorization Events +We are going to adjust the vyos configuration to send authentication messages from fw01 to log01. Note, vyos does produce a ton of useless authentication messages which we are going to have to deal with at some point. +- first, [change the default password](https://git.charlotte.sh/lotte/ChamplainTechJournals/src/branch/main/net-sec-controls-sec350/week01/vyos.md#change-password) : `set system login user vyos authentication plaintext-password password123!` +- `set system syslog host 172.16.50.5 facility authpriv level info` \ +![image](../../../assets/57d3e4d5-2d74-45c7-91e1-7e0066bcaf10.png) \ +![image](../../../assets/26d035b6-8587-4277-ac33-3b4824459cc8.png) + + diff --git a/net-sec-controls-sec350/labs/week02/centOS_repo_fix.md b/net-sec-controls-sec350/labs/week02/centOS_repo_fix.md new file mode 100644 index 0000000..5f1d1ac --- /dev/null +++ b/net-sec-controls-sec350/labs/week02/centOS_repo_fix.md @@ -0,0 +1,7 @@ +# CentOS Repo Fix +They changed the URLs for the repos for CentOS. to fix, change the repos in yum's config: +``` +sudo sed -i s/mirror.centos.org/vault.centos.org/g /etc/yum.repos.d/CentOS-*.repo +sudo sed -i s/^#.*baseurl=http/baseurl=http/g /etc/yum.repos.d/CentOS-*.repo +sudo sed -i s/^mirrorlist=http/#mirrorlist=http/g /etc/yum.repos.d/CentOS-*.repo +``` diff --git a/net-sec-controls-sec350/labs/week03/lab3.1-segmentation-1.md b/net-sec-controls-sec350/labs/week03/lab3.1-segmentation-1.md new file mode 100644 index 0000000..87f2c82 --- /dev/null +++ b/net-sec-controls-sec350/labs/week03/lab3.1-segmentation-1.md @@ -0,0 +1,80 @@ +# Lab 3.1 Segmentation 1 +In this lab, we are going to segment our network by adding a new firewall and a new network (MGMT). We will retire our log01 server and replace it with a new server on the MGMT network. + +___ +# if you got this far...you can shutdown log01. this machine is no longer needed +- shutdown log01 +- On web01, remove your rsyslog dropin configuration from `/etc/rsyslog.d` (comment out the `user.notice` and `authpriv.*` lines) +- On fw01, remove syslog host setting from configuration: `delete system syslog host 172.16.50.5` +___ + + +## configure wks01 (LAN) +- IP Address: 172.16.150.50\24 +- Gateway: 172.16.150.2 +- DNS: 172.16.150.2 + + +## fw01 - create a rule for NAT from MGMT to WAN +``` +set nat source rule 30 description "NAT FROM MGMT to WAN" +set nat source rule 30 outbound-interface eth0 +set nat source rule 30 source address 172.16.200.0/28 +set nat source rule 30 translation address masquerade +``` + + +## fw-mgmt + +![image](../../../assets/e9fe5785-ef2b-4efa-9cc2-f10c25cc9476.png) \ +Configure your fw-mgmt firewall's hostname with interface descriptions and interface addresses: +- eth0: LAN- 172.16.150.3/24 +- eth1: MGMT- 172.16.200.2/28 (NOTE: MGMT is using a /28!) +``` +set interfaces ethernet eth0 description LAN +set interfaces ethernet eth1 description MGMT +set interfaces ethernet eth0 address 172.16.150.3/24 +set interfaces ethernet eth1 address 172.16.200.2/28 +``` +![image](../../../assets/68f108b9-2a62-4575-9614-c2ec286093ad.png) + +Set the following: +- gateway next-hop: `set protocols static route 0.0.0.0/0 next-hop 172.16.150.2` +- name server to your fw01’s LAN interface address: `set system name-server 172.16.150.2` +- dns forwarding such that requests are allowed from your management subnet and management interface. +``` +set service dns forwarding listen-address 172.16.200.2 +set service dns forwarding allow-from 172.16.200.0/28 +set service dns forwarding system +``` + +## configure mgmt02 (MGMT) +- IP Address: 172.16.200.11/28 +- Gateway: 172.16.200.2 +- DNS: 172.16.200.2 + + +## RIP on FW1 and FW-MGMT +fw01 +``` +set protocols rip interface eth2 +set protocols rip network '172.16.50.0/29' +``` +fw-mgmt +``` +set protocols rip interface eth0 +set protocols rip network '172.16.200.0/28' +``` + + +## configure jump | wazuh-charlotte (MGMT) +- IP: 172.16.200.10/28 +- Gateway: 172.16.200.2 +- DNS: 172.16.200.2 + +### netplan configuration (an alternative to nmtui) +/etc/netplan/00-installer-config.yaml is the config file +![image](../../../assets/fee62fbf-d5a3-4564-a8a4-2c09ee5e3a9e.png) + +`sudo netplan apply` +`sudo hostnamectl hostname wazuh-charlotte` diff --git a/net-sec-controls-sec350/labs/week03/lab3.2-wazuh.md b/net-sec-controls-sec350/labs/week03/lab3.2-wazuh.md new file mode 100644 index 0000000..28bad71 --- /dev/null +++ b/net-sec-controls-sec350/labs/week03/lab3.2-wazuh.md @@ -0,0 +1,39 @@ +# Lab 3.2 - Wazuh +In this lab, we are going to experiment with a far more modern logging system called Wazuh. Wazuh is one of several ELK based SIEMs. We are using this one because of the relatively ease of installation as well as functionality. Unlike a traditionally syslog client and server, Wazuh allows us to install agents on supported systems. Agents can refine that information sent to their SIEM for streamlined analysis. + +>[!Warning] +>TAKE A SNAPSHOT BEFORE INSTALLATION + +## Installation +For a single node installation on wazuh, run the following command. +`curl -sO https://packages.wazuh.com/4.7/wazuh-install.sh && sudo bash ./wazuh-install.sh -a -i` +(added -i to ignore minimum requirements of 2CPU and 4 GB RAM) + +>[!Note] +>Save the auto-generated password, you will need it later + +## Wazuh/OSSEC Agent on web01 +- Wazuh dropdown > management > groups > create a new group called linux +- Wazuh dropdown > agents > Deploy a new agent with the following configuration. + - Redhat/CentoS + - CentOS 6 or higher (Note, it will work on rocky 8) + - x86_64 + - 172.16.200.10 + - Linux +- run the generated command on web01 to install the agent: +``` +curl -o wazuh-agent-4.7.5-1.x86_64.rpm https://packages.wazuh.com/4.x/yum/wazuh-agent-4.7.5-1.x86_64.rpm && sudo WAZUH_MANAGER='172.16.200.10' WAZUH_AGENT_GROUP='linux' WAZUH_AGENT_NAME='web01-charlotte' rpm -ihv wazuh-agent-4.7.5-1.x86_64.rpm +``` +- if you can't access through a web browser. try going to http://172.16.200.10/app/login. for some reason this worked for me +![image](../../../assets/c6c6ae88-635e-4db1-a1d3-e1473bf63653.png) +![image](../../../assets/1609a92a-ffe2-4d93-8477-f6669a95c2f5.png) + +- start the agent +``` +sudo systemctl daemon-reload +sudo systemctl enable wazuh-agent +sudo systemctl start wazuh-agent +``` + +## to view security events +dropdown > modules > security events diff --git a/net-sec-controls-sec350/labs/week04/lab4.1-network-firewalls1.md b/net-sec-controls-sec350/labs/week04/lab4.1-network-firewalls1.md new file mode 100644 index 0000000..440b9ac --- /dev/null +++ b/net-sec-controls-sec350/labs/week04/lab4.1-network-firewalls1.md @@ -0,0 +1,201 @@ +# network firewalls 1 + +# Configure fw01 +- Create and link firewall zones to interfaces (eth0, eth1, eth2) +``` +set zone-policy zone WAN interface eth0 +set zone-policy zone DMZ interface eth1 +set zone-policy zone LAN interface eth2 +``` + +### WAN and DMZ firewalls +In the illustration below, we have created firewalls for WAN to DMZ and DMZ to WAN, +we are going to lock them down with a default drop directive, and we will log violations of the firewall rules. +We have also assigned firewalls to the respective direction of communication between zones. + +Firewalls for WAN and DMZ +``` +set firewall name WAN-to-DMZ default-action drop +set firewall name DMZ-to-WAN default-action drop +set firewall name WAN-to-DMZ enable-default-log +set firewall name DMZ-to-WAN enable-default-log +``` + +Assigning Firewalls to Zones +``` +set zone-policy zone WAN from DMZ firewall name DMZ-to-WAN +set zone-policy zone DMZ from WAN firewall name WAN-to-DMZ +``` + +On fw01, monitor your firewall logs with the following command: +`tail -f /var/log/messages | grep WAN` + + +## Allow http inbound +``` +set firewall name WAN-to-DMZ rule 10 description "Allow HTTP from WAN to DMZ" +set firewall name WAN-to-DMZ rule 10 action accept +set firewall name WAN-to-DMZ rule 10 destination address 172.16.50.3 +set firewall name WAN-to-DMZ rule 10 destination port 80 +set firewall name WAN-to-DMZ rule 10 protocol tcp +``` +## allow return traffic +this won't work if you try to ping/curl, because traffic back out to WAN is still blocked +these commands will allow established connection through DMZ-to-WAN +``` +set firewall name DMZ-to-WAN rule 1 action accept +set firewall name DMZ-to-WAN rule 1 state established enable +``` + + +>[!Note] +>We will reserve rule 1 for two conditions. The first is to allow established connections back out again, the second would be to have an open rule where all connections are allowed. Typically this would be the only rule in such a firewall. + +## DMZ and LAN Traffic Firewalls + +``` +set firewall name LAN-to-DMZ default-action drop +set firewall name DMZ-to-LAN default-action drop +set firewall name LAN-to-DMZ enable-default-log +set firewall name DMZ-to-LAN enable-default-log +``` + +Assigning Firewalls to Zones +``` +set zone-policy zone LAN from DMZ firewall name DMZ-to-LAN +set zone-policy zone DMZ from LAN firewall name LAN-to-DMZ +``` + +### allow ports 1514 and 1515 +``` +set firewall name DMZ-to-LAN rule 10 description "wazuh agent communication with server" +set firewall name DMZ-to-LAN rule 10 action accept +set firewall name DMZ-to-LAN rule 10 destination address 172.16.200.10 +set firewall name DMZ-to-LAN rule 10 destination port 1514,1515 +set firewall name DMZ-to-LAN rule 10 protocol tcp +``` + +### allow return traffic from DMZ +``` +set firewall name DMZ-to-LAN rule 1 action accept +set firewall name DMZ-to-LAN rule 1 state established enable +``` + + +### allow return traffic from LAN +``` +set firewall name LAN-to-DMZ rule 1 action accept +set firewall name LAN-to-DMZ rule 1 state established enable +``` + +## lan to wan? +yes, clients usually need direct access to internet. we will have to configure proxies for this later\ +Create a default LAN to WAN firewall and associate it with the appropriate zone policy. This firewall will have only one rule allowing LAN clients to initiate WAN connections. +``` +set zone-policy zone WAN from LAN firewall name LAN-to-WAN +set firewall name LAN-to-WAN default-action drop +set firewall name LAN-to-WAN enable-default-log +set firewall name LAN-to-WAN rule 1 action accept +``` +### allow return traffic WAN to LAN +``` +set zone-policy zone LAN from WAN firewall name WAN-to-LAN +set firewall name WAN-to-LAN default-action drop +set firewall name WAN-to-LAN enable-default-log +set firewall name WAN-to-LAN rule 1 action accept +set firewall name WAN-to-LAN rule 1 state established enable +``` + +## LAN to DMZ +As communication between LAN and DMZ is currently broken, we need to create a firewall, assign to the appropriate zone policy and adjust it to only allow the traffic we want to go through. We want wks01 to be able to browse to web01 and we want mgmt01 to ssh into anything on the DMZ. + +With that in mind, create firewall rules on LAN-TO-DMZ that allows +- 80/tcp from LAN to web01. + +``` +set firewall name LAN-to-DMZ rule 10 description "Allow HTTP from LAN to DMZ" +set firewall name LAN-to-DMZ rule 10 action accept +set firewall name LAN-to-DMZ rule 10 destination address 172.16.50.3 +set firewall name LAN-to-DMZ rule 10 destination port 80 +set firewall name LAN-to-DMZ rule 10 protocol tcp +``` +- 22/tcp from mgmt01 to the DMZ +``` +set firewall name LAN-to-DMZ rule 20 description "Allow SSH from MGMT-01 to DMZ" +set firewall name LAN-to-DMZ rule 20 action accept +set firewall name LAN-to-DMZ rule 20 source address 172.16.150.10 +set firewall name LAN-to-DMZ rule 20 destination port 22 +set firewall name LAN-to-DMZ rule 20 protocol tcp +``` + +# Configure fw-mgmt +## LAN-to-MGMT +``` +set zone-policy zone LAN interface eth0 +set zone-policy zone MGMT interface eth1 +``` +Firewalls for WAN and DMZ +``` +set firewall name LAN-to-MGMT default-action drop +set firewall name MGMT-to-LAN default-action drop +set firewall name LAN-to-MGMT enable-default-log +set firewall name MGMT-to-LAN enable-default-log +``` + +Assigning Firewalls to Zones +``` +set zone-policy zone MGMT from LAN firewall name LAN-to-MGMT +set zone-policy zone LAN from MGMT firewall name MGMT-to-LAN +``` + +### LAN-to-MGMT firewall +allow established traffic +``` +set firewall name LAN-to-MGMT rule 1 action accept +set firewall name LAN-to-MGMT rule 1 state established enable +``` +allow SSH MGMT-01->wazuh +``` +set firewall name LAN-to-MGMT rule 10 description "wazuh SSH access from MGMT-01" +set firewall name LAN-to-MGMT rule 10 action accept +set firewall name LAN-to-MGMT rule 10 source address 172.16.150.10 +set firewall name LAN-to-MGMT rule 10 destination address 172.16.200.10 +set firewall name LAN-to-MGMT rule 10 destination port 22 +set firewall name LAN-to-MGMT rule 10 protocol tcp +``` +allow HTTPS MGMT-01->wazuh +``` +set firewall name LAN-to-MGMT rule 20 description "wazuh HTTPS access from MGMT-01" +set firewall name LAN-to-MGMT rule 20 action accept +set firewall name LAN-to-MGMT rule 20 source address 172.16.150.10 +set firewall name LAN-to-MGMT rule 20 destination address 172.16.200.10 +set firewall name LAN-to-MGMT rule 20 destination port 443 +set firewall name LAN-to-MGMT rule 20 protocol tcp +``` +allow wazuh agent communication +``` +set firewall name LAN-to-MGMT rule 30 description "wazuh agent communication with server" +set firewall name LAN-to-MGMT rule 30 action accept +set firewall name LAN-to-MGMT rule 30 destination address 172.16.200.10 +set firewall name LAN-to-MGMT rule 30 destination port 1514,1515 +set firewall name LAN-to-MGMT rule 30 protocol tcp +``` + +## MGMT-to-LAN +Allows established traffic back again +``` +set firewall name MGMT-to-LAN rule 1 action accept +set firewall name MGMT-to-LAN rule 1 state established enable +``` +Allows MGMT to initiate any connection to the LAN +``` +set firewall name MGMT-to-LAN rule 10 description "allows MGMT to LAN" +set firewall name MGMT-to-LAN rule 10 action accept +set firewall name MGMT-to-LAN rule 10 destination address 172.16.150.0/24 +``` +Allows MGMT to initiate any connection to the DMZ (yes, this is in the MGMT-to-LAN zone-policy, because MGMT is not directly connected to DMZ) +``` +set firewall name MGMT-to-LAN rule 20 description "allows MGMT to DMZ" +set firewall name MGMT-to-LAN rule 20 action accept +set firewall name MGMT-to-LAN rule 20 destination address 172.16.50.0/29 +``` diff --git a/net-sec-controls-sec350/labs/week05/lab5.1-wazuh-waf.md b/net-sec-controls-sec350/labs/week05/lab5.1-wazuh-waf.md new file mode 100644 index 0000000..d4d5cb9 --- /dev/null +++ b/net-sec-controls-sec350/labs/week05/lab5.1-wazuh-waf.md @@ -0,0 +1,53 @@ +# Lab 5.1 - Wazuf WAF +In this lab we are going to augment web01 by adding a web application firewall (WAF). The wazuh agent should currently be able to forward apache error logs so a good deal of our work is done for us already. We are then going to run malicious http requests against web01 to see how our WAF performs. + +## patch fw01 +>[!Warning] +> web01's ability to talk to the WAN and the WANs ability to talk to web01 might be currently restricted. Updating and patching the server is one of the things we must do from time to time. VYOS itself cannot filter by domain name such as allowing traffic to updates.centos.org. It has to be by IP address or subnet. For this reason, many organizations go to an internal mirror for this purpose. We will use a work around. + +### WAN-to-DMZ +- add a new permanent rule to vyos such that established connections from the DMZ-to-WAN are allowed back through the WAN-to-DMZ +``` +set firewall name WAN-to-DMZ rule 1 action accept +set firewall name WAN-to-DMZ rule 1 state established enable +``` +### DMZ-to-WAN +temporary rule for software updates that we either delete, disable or discard when complete +``` +set firewall name DMZ-to-WAN rule 999 action accept +set firewall name DMZ-to-WAN rule 999 source address 172.16.50.3 +``` + +## Adding mod_security, the core rule set and php to web01 +The following command will install mod_security, the core ruleset associated with this layer 7 firewall and the php necessary to make a webshell work. +``` +sudo yum install mod_security mod_security_crs php php-common php-opcache php-cli php-gd php-curl php-mysqlnd -y +``` +- after installation delete temporary rule on fw01 +``` +delete firewall name DMZ-to-WAN rule 999 +``` +- create a php webshell at `/var/www/html/shell.php` on web01 +``` + + + +
+ + +
+
+&1');
+    }
+?>
+
+ + +``` + +while this shell works for commands like `whoami` and `/sbin/ifconfig`, modsecurity will prevent dangerous commands like `cat /etc/passwd` from being executed + + diff --git a/net-sec-controls-sec350/labs/week06/lab6.1-port-forwarding-and-jump boxes.md b/net-sec-controls-sec350/labs/week06/lab6.1-port-forwarding-and-jump boxes.md new file mode 100644 index 0000000..f47cf06 --- /dev/null +++ b/net-sec-controls-sec350/labs/week06/lab6.1-port-forwarding-and-jump boxes.md @@ -0,0 +1,85 @@ +# Lab 6.1: Port Forwarding and Jump Boxes + +## RW01 -> WEB +security issue: rw01 knows the internal routing for our DMZ and used this information to create a static route from SEC350-WAN to the DMZ. A better alternative is to mask the presence of the DMZ altogether with NAT destination rules. + +- remove static ip route from rw01 to DMZ +``` +sudo ip route del 172.16.50.0/29 +``` + +## WAN to DMZ NAT +We've worked with NAT **source** rules when dealing with traffic from inside the network going out to the WAN. Now we are going to add a NAT **destination** rule (aka port forwarding) so that any port 80 traffic coming to our firewall's WAN/eth0 interface will be forwarded on to web01. +``` +set nat destination rule 10 description "HTTP->WEB01" +set nat destination rule 10 inbound-interface eth0 +set nat destination rule 10 destination port 80 +set nat destination rule 10 protocol tcp +set nat destination rule 10 translation address 172.16.50.3 +``` + +## Jump server +- log01 is back! but it's a jump server now +- IP Address: 172.16.50.4/29 +- hostname: jump-charlotte + + +- Adjust the firewall rules from LAN-TO-DMZ such that mgmt01 can ssh into any server on the DMZ. + + +- Make sure that fw01 is only listening for SSH on the LAN interface (172.16.150.2) and not on all interfaces (0.0.0.0/0) +![image](../../../assets/76304685-062f-41df-ac18-092174428aa2.png) + +sudo systemctl restart ssh + + + +On rw01, create a dedicated keypair that will only be used for ssh access to jump. make sure to name the keypair something other than the default and add a comment indicating its purpose. Make sure to add a passphrase when prompted. + +``` +ssh-keygen -t rsa -b 4096 -C "ssh to jump" +name of file: jump-charlotte +``` +(this is a public key! it's okay to share, unlike private keys) +``` +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDLLKDg5fIw8CINt5IOY3vZ6XiudxKn0sXZ1hTWbugfKQ9NZjfSCbboxIlVpyqAwnFzf+3oJcPpnlVLjXpugJe6ghfuLsO/1fdqFQ5/PBcQbJXFvdIH93MJ78sBUhT+SbhHLas6KjShSOhNz5fRYOMOTpCtB7eQhk5q3gqTEvmDejgWZPphyAQJCnB0hw+J76jl3t68Q+FtD57RWhWhp/0ZQPfjY+hnJOfLaD+Zs0tsxvYXqDuPhRt2J2xUHF8LgaqZYkosIllfcX//tmEnQ90nU+zLu3jje8Pqy4mfjGsV8wZ+ug7ModwJwR2ToieqoiyOnDq1ytG0r5sKjeM5RTX6tJTOl8ltr7E51u0bajjym0ZL4kT0W82Eld/DV4+BzbEB6yCSWWVwo/eKoqkGBIHpIibzkjPGCQ4O0tq3s+04DpOpucDqk0J+Yphdj/qmK/mYFLU0xKZnIJl8otyItyVhV2zTIn64PQ3gEE8z0O4GjEJEfhkJ29ydtXXDFIpCfSirmfH7HbXlwgUmxHJqnCBqZ8eKb/n52ekaD0SIOPQE76RmR540cus3mvo3t30Ak79NBSjEh82k2rP42eVx/GhF/o3u8DdCF3xA46dzqt1HMvOpnOjdvbldP076VKkxV/px9nE7mJZysxei8SisrSbwn7vxLem4LrDsAIxfsGcULw== ssh to jump +``` + + +create a passwordless user called `charlotte-jump` on jump. Copy over the public component of the jump keypair you just created on rw01 to the new user's `.ssh/authorized_keys` file. + +``` +useradd -m -d /home/charlotte-jump -s /bin/bash charlotte-jump +sudo sed -i 's/PasswordAuthentication.*/PasswordAuthentication no/' /etc/ssh/sshd_config + +# create .ssh directory, give perms to user +mkdir -p /home/charlotte-jump/.ssh +chmod 700 /home/charlotte-jump/.ssh + +echo "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDLLKDg5fIw8CINt5IOY3vZ6XiudxKn0sXZ1hTWbugfKQ9NZjfSCbboxIlVpyqAwnFzf+3oJcPpnlVLjXpugJe6ghfuLsO/1fdqFQ5/PBcQbJXFvdIH93MJ78sBUhT+SbhHLas6KjShSOhNz5fRYOMOTpCtB7eQhk5q3gqTEvmDejgWZPphyAQJCnB0hw+J76jl3t68Q+FtD57RWhWhp/0ZQPfjY+hnJOfLaD+Zs0tsxvYXqDuPhRt2J2xUHF8LgaqZYkosIllfcX//tmEnQ90nU+zLu3jje8Pqy4mfjGsV8wZ+ug7ModwJwR2ToieqoiyOnDq1ytG0r5sKjeM5RTX6tJTOl8ltr7E51u0bajjym0ZL4kT0W82Eld/DV4+BzbEB6yCSWWVwo/eKoqkGBIHpIibzkjPGCQ4O0tq3s+04DpOpucDqk0J+Yphdj/qmK/mYFLU0xKZnIJl8otyItyVhV2zTIn64PQ3gEE8z0O4GjEJEfhkJ29ydtXXDFIpCfSirmfH7HbXlwgUmxHJqnCBqZ8eKb/n52ekaD0SIOPQE76RmR540cus3mvo3t30Ak79NBSjEh82k2rP42eVx/GhF/o3u8DdCF3xA46dzqt1HMvOpnOjdvbldP076VKkxV/px9nE7mJZysxei8SisrSbwn7vxLem4LrDsAIxfsGcULw== ssh to jump" >> /home/charlotte-jump/.ssh/authorized_keys + +# set perms, set new user as directory owner +chmod 600 /home/charlotte-jump/.ssh/authorized_keys +chown -R charlotte-jump:charlotte-jump /home/charlotte-jump/.ssh + +systemctl restart sshd +``` + +## install wazuh agent on jump +on mgmt01 +``` +wget https://packages.wazuh.com/4.x/yum/wazuh-agent-4.7.3-1.x86_64.rpm +scp wazuh-agent-4.7.3-1.x86_64.rpm charlotte@172.16.50.4:~ +``` + +on jump +``` +scp wazuh-agent-4.7.3-1.x86_64.rpm charlotte@172.16.50.4:~ +sudo WAZUH_MANAGER='172.16.200.10' WAZUH_AGENT_GROUP='linux' WAZUH_AGENT_NAME='jump-charlotte' rpm -ihv wazuh-agent-4.7.3-1.x86_64.rpm +sudo systemctl daemon-reload +sudo systemctl enable wazuh-agent +sudo systemctl start wazuh-agent +``` +![image](../../../assets/500def07-6fb1-4fb5-82a8-4c4f433e3861.png) + + diff --git a/net-sec-controls-sec350/labs/week07/lab7.1-assessment-prep.md b/net-sec-controls-sec350/labs/week07/lab7.1-assessment-prep.md new file mode 100644 index 0000000..c92b55e --- /dev/null +++ b/net-sec-controls-sec350/labs/week07/lab7.1-assessment-prep.md @@ -0,0 +1,79 @@ +# Lab 7.1 Assessment Prep +Several systems in your current environment will be removed the day before the assessment (3/27), first thing in the morning. +- **rw01** -> **traveler** +- **fw01** -> **edge01** +- **web01** -> **nginx01** + +``` +You are on your own for the assessment. +Open notes and internet, just no open neighbor. +This is really a test of your notes. +You will be getting new VM's. +Don't be late, as you will likely need the full time. +``` + +## fw01 configuration Backup +- **edge01**: (this new firewall will be very close in configuration). +- You might also consult your the example week 4 configurations [here](../configs/fw01/fw01.config.week04.txt) + +- Provide the raw commands necessary to reconstitute your firewall: (Remember, there may be some adjustments in IP addresses and rules for your internal systems.) + + +## Assessment Description +For the assessment, you will be given a 3 zone network to configure that consists of: +- **traveler**. A WAN based road warrior user running Windows 10. (this replaces the linux rw01) +- **edge01**. A vyOS Firewall with three interfaces (WAN, DMZ, LAN). You will need to add an interface using vCenter. (this replaces fw01) +- **nginx01**. A DMZ based nginx web server running Ubuntu (this replaces web01 and apache) +- **dhcp01**. A LAN based dhcp server running Ubuntu + +## Requirements +- All systems should have an accurate hostname. +- All Linux systems should have a named sudo or administrator user. +- The two new ubuntu systems do not have a host firewall enabled, this is ok (for now) +- wks1, mgmt01 should be able to surf the internet. +- wks1, mgmt01 should be able to navigate to nginx01 +- mgmt01 should be able to ssh to nginx01 +- nginx01 and dhcp01 should have wazuh agents installed and be able to connect to wazuh +- nginx01 should have a custom web page (practice this on jump) +- traveler should be able to get to nginx01's custom test page by navigating to edge01's WAN IP address. +- traveler should be able to perform ssh keybased authentication with jump. Traveler is a Windows box, but ssh on powershell is nearly exactly the same as linux to include key generation. You will need to add a new public key to authorized_keys. +- dhcp01 should serve a pool of dhcp addresses to the LAN from .100 to .150. +- WKS1 should use dhcp addressing + +## Hints +- You do not need to work serially through this assessment, it is the end result that matters. If you are waiting for a reboot on traveler, then start configuring your other servers. +- Get all communications working BEFORE creating zones and locking down the firewalls. It's terribly difficult to debug both services and network firewalls at the same time. +- Make sure to link your firewalls to the appropriate From and To zones. +- Make sure you have the correct netmask on all Linux systems. +- Restart any service if you touch a configuration file (network, nginx, rsyslog, etc…). +- Make sure you include the appropriate vsphere label on all deliverables where your name is not obvious in the console. +- Check every VM's network settings to make sure they are on the correct segment. +- Don't forget to look at `/var/log/messages` to debug firewall issues. +- Do not try to use the default gateway address 10.0.17.2 as your WAN interface IP address as this will cause problems for other students and might be embarrassing. + + +## Nginx Web Server +Practice this on jump (it is an ubuntu box). + + +## Ubuntu DHCP Server +You can also practice this on jump, just move it to LAN, change the IP to something else and see if you can get wks01 to use dhcp services for IP, Netmask, Gateway and DNS settings. Make sure to reset wks01 to static. + +## Traveler is a Windows System +You should research how to create a keypair using powershell or putty and make sure you can adjust jumps authorized_keys file to use your new windows public key. + +## Deliverable 3. Practice this on either mgmt02 or wks01. Figure out how to create a keypair using either powershell or PuTTY, transfer the public portion to one of your linux systems and demonstrate a passwordless login from windows to a linux system. + +## Clearing the firewall configuration +You should rehearse vyos commands by clearing your current configuration. The following commands will do that. Note, this configuration will likely have the vyos/vyos password combination because that is what it ships with. + +``` +configure +load /opt/vyatta/etc/config.boot.default +commit +save + +# to save and load a backup config file +save backup_1 +load /config/backup_1 +``` diff --git a/net-sec-controls-sec350/labs/week09/lab9.1-AdHocVPN.md b/net-sec-controls-sec350/labs/week09/lab9.1-AdHocVPN.md new file mode 100644 index 0000000..dc85157 --- /dev/null +++ b/net-sec-controls-sec350/labs/week09/lab9.1-AdHocVPN.md @@ -0,0 +1,50 @@ +# Lab 9.1 - Ad Hoc VPN with SSH +SSH allows you to create a remote port forwarding tunnel such that connections to a local port on traveler will traverse an ssh tunnel from traveler to jump and then be forwarded to a system of your choice, say mgmt02. + +- Enable RDP on mgmt02 +- Create a named local administrator account (charlotte) if not done so already +- Create the DMZ-to-LAN and LAN-to-MGMT rules necessary for RDP to connect to mgmt02 +``` +# on edge-02 +set firewall name DMZ-to-LAN rule 40 action 'accept' +set firewall name DMZ-to-LAN rule 40 description 'jump to RDP' +set firewall name DMZ-to-LAN rule 40 destination address '172.16.200.11' +set firewall name DMZ-to-LAN rule 40 destination port '3389' +set firewall name DMZ-to-LAN rule 40 protocol 'tcp' + +# on fw-mgmt +set firewall name LAN-to-MGMT rule 40 action 'accept' +set firewall name LAN-to-MGMT rule 40 description 'jump to RDP' +set firewall name LAN-to-MGMT rule 40 destination address '172.16.200.11' +set firewall name LAN-to-MGMT rule 40 destination port '3389' +set firewall name LAN-to-MGMT rule 40 protocol 'tcp' +``` + +source: https://www.cloudthat.com/resources/blog/a-guide-to-access-rdp-through-ssh-tunneling-using-putty +## Invoke an SSH connection from traveler to jump such that RDP connections in that tunnel are redirected to mgmt02. +### Step 1: Configure PuTTY for SSH Tunneling +- Launch PuTTY on your source Windows machine +- In the "Session" category: + - Enter the IP of jump box[actually the firewall interface -PF] (10.0.17.151) + - Keep port 22 / SSH + - Optionally save your session configuration + +### Step 2: Set Up the SSH Tunnel for RDP +- In the PuTTY Configuration window, navigate to Connection > SSH > Tunnels +- Configure the tunnel with: + - Source port: 3390 (or any unused local port) + - Destination: 172.16.200.11:3389 (mgmt02) + - Select "Local" and "Auto" options + - Click "Add" to create the tunnel + +### Step 3: Connect to the Jump Box +- Return to the "Session" category +- save your configuration +- Click "Open" to connect to the Linux jump box/ enter jump box creds + +### Step 4: Connect via RDP Through the Tunnel +- With the SSH connection active, open Remote Desktop Connection on your source Windows machine +- In the "Computer" field, enter: localhost:3390 +- Click "Connect" and enter credentials for the destination Windows machine + + diff --git a/net-sec-controls-sec350/machines/DHCP01.md b/net-sec-controls-sec350/machines/DHCP01.md new file mode 100644 index 0000000..0373fd9 --- /dev/null +++ b/net-sec-controls-sec350/machines/DHCP01.md @@ -0,0 +1,57 @@ +# DHCP01 Configuration +## Basic Setup +- Set hostname to `dhcp01-charlotte` +- Add sudo user `charlotte` + +Set network via netplan: +- IP Address: `172.16.150.151/24` +- Gateway & DNS: `172.16.150.2` +- Network adapter: LAN + + +## Install and Configure DHCP Server + +Install DHCP server +```bash +sudo apt update +sudo apt install isc-dhcp-server -y +``` +Configure DHCP server +```bash +> sudo nano /etc/dhcp/dhcpd.conf + +default-lease-time 600; +max-lease-time 7200; +option subnet-mask 255.255.255.0; +option broadcast-address 172.16.150.255; +option routers 172.16.150.2; +option domain-name-servers 172.16.150.2; + +subnet 172.16.150.0 netmask 255.255.255.0 { + range 172.16.150.100 172.16.150.150; +} +``` +Configure the interface for DHCP server: +```bash +> sudo nano /etc/default/isc-dhcp-server +... +INTERFACESv4="ens160" +INTERFACESv6="" +... +``` +Start and enable DHCP server +```bash +sudo systemctl enable isc-dhcp-server +sudo systemctl restart isc-dhcp-server +``` + +## Install Wazuh Agent +```bash +# Download and install Wazuh agent +curl -o wazuh-agent-4.7.5-1.amd64.deb https://packages.wazuh.com/4.x/apt/pool/main/w/wazuh-agent/wazuh-agent-4.7.5-1.amd64.deb && sudo WAZUH_MANAGER='172.16.200.10' WAZUH_AGENT_GROUP='linux' WAZUH_AGENT_NAME='dhcp01-charlotte' dpkg -i wazuh-agent-4.7.5-1.amd64.deb + +# Start the agent +sudo systemctl daemon-reload +sudo systemctl enable wazuh-agent +sudo systemctl start wazuh-agent +``` diff --git a/net-sec-controls-sec350/machines/EDGE01.md b/net-sec-controls-sec350/machines/EDGE01.md new file mode 100644 index 0000000..302ef4d --- /dev/null +++ b/net-sec-controls-sec350/machines/EDGE01.md @@ -0,0 +1,197 @@ +# EDGE01 Configuration + +## Initial Setup +- Change password: +``` +configure +set system login user vyos authentication plaintext-password password123! +commit +save +``` +- Change hostname: +``` +configure +set system host-name edge01-charlotte +commit +save +``` + +## Interface Configuration +``` +configure +set interfaces ethernet eth0 description SEC350-WAN +set interfaces ethernet eth1 description CHARLOTTE-DMZ +set interfaces ethernet eth2 description CHARLOTTE-LAN +set interfaces ethernet eth0 address 10.0.17.151/24 +set interfaces ethernet eth1 address 172.16.50.2/29 +set interfaces ethernet eth2 address 172.16.150.2/24 +commit +save +``` +## Gateway and DNS Configuration +``` +configure +set protocols static route 0.0.0.0/0 next-hop 10.0.17.2 +set system name-server 10.0.17.2 +commit +save +``` +## NAT Configuration +``` +configure +# DMZ to WAN NAT +set nat source rule 10 description "NAT FROM DMZ to WAN" +set nat source rule 10 outbound-interface eth0 +set nat source rule 10 source address 172.16.50.0/29 +set nat source rule 10 translation address masquerade + +# LAN to WAN NAT +set nat source rule 20 description "NAT FROM LAN to WAN" +set nat source rule 20 outbound-interface eth0 +set nat source rule 20 source address 172.16.150.0/24 +set nat source rule 20 translation address masquerade + +# MGMT to WAN NAT +set nat source rule 30 description "NAT FROM MGMT to WAN" +set nat source rule 30 outbound-interface eth0 +set nat source rule 30 source address 172.16.200.0/28 +set nat source rule 30 translation address masquerade + +# Port Forwarding for HTTP +set nat destination rule 10 description "HTTP->NGINX01" +set nat destination rule 10 inbound-interface eth0 +set nat destination rule 10 destination port 80 +set nat destination rule 10 protocol tcp +set nat destination rule 10 translation address 172.16.50.3 + +# Port Forwarding for SSH +set nat destination rule 20 description "SSH->JUMP" +set nat destination rule 20 inbound-interface eth0 +set nat destination rule 20 destination port 22 +set nat destination rule 20 protocol tcp +set nat destination rule 20 translation address 172.16.50.4 + +commit +save +``` +## DNS Forwarding Configuration +``` +configure +# DMZ DNS Forwarding +set service dns forwarding listen-address 172.16.50.2 +set service dns forwarding allow-from 172.16.50.0/29 + +# LAN DNS Forwarding +set service dns forwarding listen-address 172.16.150.2 +set service dns forwarding allow-from 172.16.150.0/24 + +set service dns forwarding system +commit +save +``` + +## Zone Configuration +``` +configure +set zone-policy zone WAN interface eth0 +set zone-policy zone DMZ interface eth1 +set zone-policy zone LAN interface eth2 +commit +save +``` + +## Firewall Configuration +``` +configure +# Create Zone-Based Firewalls + +# WAN-to-DMZ +set firewall name WAN-to-DMZ default-action drop +set firewall name WAN-to-DMZ enable-default-log +set firewall name WAN-to-DMZ rule 1 action accept +set firewall name WAN-to-DMZ rule 1 state established enable +set firewall name WAN-to-DMZ rule 10 description "allow HTTP from WAN to DMZ" +set firewall name WAN-to-DMZ rule 10 action accept +set firewall name WAN-to-DMZ rule 10 destination address 172.16.50.3 +set firewall name WAN-to-DMZ rule 10 destination port 80 +set firewall name WAN-to-DMZ rule 10 protocol tcp + +set firewall name WAN-to-DMZ rule 20 action accept +set firewall name WAN-to-DMZ rule 20 description "SSH to JUMP" +set firewall name WAN-to-DMZ rule 20 destination address 172.16.50.4 +set firewall name WAN-to-DMZ rule 20 destination port 22 +set firewall name WAN-to-DMZ rule 20 protocol tcp + + +# DMZ-to-WAN +set firewall name DMZ-to-WAN default-action drop +set firewall name DMZ-to-WAN enable-default-log +set firewall name DMZ-to-WAN rule 1 action accept +set firewall name DMZ-to-WAN rule 1 state established enable + +# LAN-to-DMZ +set firewall name LAN-to-DMZ default-action drop +set firewall name LAN-to-DMZ enable-default-log +set firewall name LAN-to-DMZ rule 1 action accept +set firewall name LAN-to-DMZ rule 1 state established enable +set firewall name LAN-to-DMZ rule 10 description "Allow HTTP from LAN to DMZ" +set firewall name LAN-to-DMZ rule 10 action accept +set firewall name LAN-to-DMZ rule 10 destination address 172.16.50.3 +set firewall name LAN-to-DMZ rule 10 destination port 80 +set firewall name LAN-to-DMZ rule 10 protocol tcp +set firewall name LAN-to-DMZ rule 20 description "Allow SSH from MGMT-01 to DMZ" +set firewall name LAN-to-DMZ rule 20 action accept +set firewall name LAN-to-DMZ rule 20 destination port 22 +set firewall name LAN-to-DMZ rule 20 protocol tcp +set firewall name LAN-to-DMZ rule 20 source address 172.16.150.10 + +# DMZ-to-LAN +set firewall name DMZ-to-LAN default-action drop +set firewall name DMZ-to-LAN enable-default-log +set firewall name DMZ-to-LAN rule 1 action accept +set firewall name DMZ-to-LAN rule 1 state established enable +set firewall name DMZ-to-LAN rule 10 description "wazuh agent communication with server" +set firewall name DMZ-to-LAN rule 10 action accept +set firewall name DMZ-to-LAN rule 10 destination address 172.16.200.10 +set firewall name DMZ-to-LAN rule 10 destination port 1514,1515 +set firewall name DMZ-to-LAN rule 10 protocol tcp + +# LAN-to-WAN +set firewall name LAN-to-WAN default-action drop +set firewall name LAN-to-WAN enable-default-log +set firewall name LAN-to-WAN rule 1 action accept + +# WAN-to-LAN +set firewall name WAN-to-LAN default-action drop +set firewall name WAN-to-LAN enable-default-log +set firewall name WAN-to-LAN rule 1 action accept +set firewall name WAN-to-LAN rule 1 state established enable + +# Apply Zone Policies +set zone-policy zone DMZ from LAN firewall name LAN-to-DMZ +set zone-policy zone DMZ from WAN firewall name WAN-to-DMZ +set zone-policy zone LAN from DMZ firewall name DMZ-to-LAN +set zone-policy zone LAN from WAN firewall name WAN-to-LAN +set zone-policy zone WAN from DMZ firewall name DMZ-to-WAN +set zone-policy zone WAN from LAN firewall name LAN-to-WAN + +commit +save +``` +## Rip Configuration +``` +configure +set protocols rip interface eth2 +set protocols rip network '172.16.50.0/29' +commit +save +``` + +## SSH Configuration +``` +# Restrict SSH access to LAN interface only +configure +set service ssh listen-address 172.16.150.2 +commit +save +``` \ No newline at end of file diff --git a/net-sec-controls-sec350/machines/FW-MGMT.md b/net-sec-controls-sec350/machines/FW-MGMT.md new file mode 100644 index 0000000..bbe91f6 --- /dev/null +++ b/net-sec-controls-sec350/machines/FW-MGMT.md @@ -0,0 +1,52 @@ +# FW-MGMT Configuration + +## Interface Configuration +``` +configure +set interfaces ethernet eth0 description LAN +set interfaces ethernet eth1 description MGMT +set interfaces ethernet eth0 address 172.16.150.3/24 +set interfaces ethernet eth1 address 172.16.200.2/28 +commit +save +``` + +## Gateway & DNS Configuration +``` +configure +set protocols static route 0.0.0.0/0 next-hop 172.16.150.2 +set system name-server 172.16.150.2 +commit +save +``` + +## DNS Forwarding +``` +configure +set service dns forwarding listen-address 172.16.200.2 +set service dns forwarding allow-from 172.16.200.0/28 +set service dns forwarding system +commit +save +``` + +## Zone Configuration +``` +configure +set zone-policy zone LAN interface eth0 +set zone-policy zone MGMT interface eth1 +commit +save +``` + +## Firewall Configuration +copy current configuration form `configs` directory + +## RIP Configuration +``` +configure +set protocols rip interface eth0 +set protocols rip network '172.16.200.0/28' +commit +save +``` diff --git a/net-sec-controls-sec350/machines/FW01.md b/net-sec-controls-sec350/machines/FW01.md new file mode 100644 index 0000000..77dd966 --- /dev/null +++ b/net-sec-controls-sec350/machines/FW01.md @@ -0,0 +1,109 @@ +# FW01 Configuration + +## Initial Setup +- Change password: +``` +set system login user vyos authentication plaintext-password password +``` + +## Hostname Configuration +``` +configure +set system host-name fw01-charlotte +commit +save +``` + +## Interface Configuration +``` +configure +set interfaces ethernet eth0 description SEC350-WAN +set interfaces ethernet eth1 description CHARLOTTE-DMZ +set interfaces ethernet eth2 description CHARLOTTE-LAN +set interfaces ethernet eth0 address 10.0.17.151/24 +set interfaces ethernet eth1 address 172.16.50.2/29 +set interfaces ethernet eth2 address 172.16.150.2/24 +commit +save +``` + +## Gateway & DNS Configuration +``` +configure +set protocols static route 0.0.0.0/0 next-hop 10.0.17.2 +set system name-server 10.0.17.2 +commit +save +``` + +## NAT Configuration +``` +configure +# DMZ to WAN NAT +set nat source rule 10 description "NAT FROM DMZ to WAN" +set nat source rule 10 outbound-interface eth0 +set nat source rule 10 source address 172.16.50.0/29 +set nat source rule 10 translation address masquerade + +# LAN to WAN NAT +set nat source rule 20 description "NAT FROM LAN to WAN" +set nat source rule 20 outbound-interface eth0 +set nat source rule 20 source address 172.16.150.0/24 +set nat source rule 20 translation address masquerade + +# MGMT to WAN NAT +set nat source rule 30 description "NAT FROM MGMT to WAN" +set nat source rule 30 outbound-interface eth0 +set nat source rule 30 source address 172.16.200.0/28 +set nat source rule 30 translation address masquerade + +commit +save +``` + +## DNS Forwarding Configuration +``` +configure +# DMZ DNS Forwarding +set service dns forwarding listen-address 172.16.50.2 +set service dns forwarding allow-from 172.16.50.0/29 + +# LAN DNS Forwarding +set service dns forwarding listen-address 172.16.150.2 +set service dns forwarding allow-from 172.16.150.0/24 + +set service dns forwarding system +commit +save +``` + +## Zone Configuration +``` +configure +set zone-policy zone WAN interface eth0 +set zone-policy zone DMZ interface eth1 +set zone-policy zone LAN interface eth2 +commit +save +``` + +## Firewall Configuration +copy current configuration from `configs` directory + +## RIP Configuration +``` +configure +set protocols rip interface eth2 +set protocols rip network '172.16.50.0/29' +commit +save +``` + +## Syslog Configuration (remove when appropriate) +``` +# When log01 is active +set system syslog host 172.16.50.5 facility authpriv level info + +# When log01 is retired +delete system syslog host 172.16.50.5 +``` diff --git a/net-sec-controls-sec350/machines/LOG01.md b/net-sec-controls-sec350/machines/LOG01.md new file mode 100644 index 0000000..1f4990c --- /dev/null +++ b/net-sec-controls-sec350/machines/LOG01.md @@ -0,0 +1,123 @@ +# LOG01 Configuration + +> **Note**: This is the original log01 server that will eventually be retired, then brought back as a jump server. + +## Basic Setup +- Set hostname to `log01-charlotte` +- Add sudo user `charlotte:password` +- Set network adapter to DMZ +- Configure static IP via nmtui: + - IP Address: `172.16.50.5/29` + - Gateway & DNS: `172.16.50.2` + +## Configure Firewall for Syslog +``` +sudo firewall-cmd --add-port=514/tcp --permanent +sudo firewall-cmd --add-port=514/udp --permanent +sudo firewall-cmd --reload +``` + +## Configure Rsyslog + +### Enable Syslog Input Modules +Edit `/etc/rsyslog.conf` and uncomment these lines: +``` +# Provides UDP syslog reception +module(load="imudp") +input(type="imudp" port="514") + +# Provides TCP syslog reception +module(load="imtcp") +input(type="imtcp" port="514") +``` + +### Configure High Precision Timestamps +Add to `/etc/rsyslog.conf`: +``` +$ActionFileDefaultTemplate RSYSLOG_SyslogProtocol23Format +template(name="BetterTiming" type="string" string="%timestamp:::date-rfc3339% %HOSTNAME% %syslogtag%%msg%\n") +``` + +Apply the template to the desired log file: +``` +# Example: Add ;BetterTiming suffix to a log destination +*.info;mail.none;authpriv.none;cron.none /var/log/messages;BetterTiming +``` + +### Configure Log Organization +Create a file named `/etc/rsyslog.d/sec350.conf` with these contents: +``` +# Input modules +module(load="imudp") +input(type="imudp" port="514") +module(load="imtcp") +input(type="imtcp" port="514") + +# Creating templates for storing logs dynamically +$template DynFile,"/var/log/%HOSTNAME%/%$YEAR%/%$MONTH%/%$DAY%/%programname%.log" +$template RemoteLogs,"/var/log/remote/%HOSTNAME%/%$YEAR%/%$MONTH%/%$DAY%/%programname%.log" + +# Create a ruleset for remote devices +ruleset(name="RemoteDevice"){ + action(type="omfile" dynaFile="RemoteLogs") +} + +# Direct local logs to files +:programname, !startswith, "rsyslog" ?DynFile + +# Direct messages from remote hosts to the ruleset +:inputname, isequal, "imudp" call RemoteDevice +:inputname, isequal, "imtcp" call RemoteDevice +``` + +### Restart Rsyslog +``` +sudo systemctl restart rsyslog +``` + +## Monitor Incoming Logs +``` +tail -f /var/log/messages +``` + +Or check specific remote log files: +``` +tail -f /var/log/remote/*/*/*/*/sshd.log +``` + +## Recommissioned as Jump Server +When log01 is repurposed as a jump server: + +1. Change IP address to: `172.16.50.4/29` +2. Change hostname: `sudo hostnamectl set-hostname jump-charlotte` + +### SSH Configuration for Passwordless Access +```bash +# Create dedicated user for jump access +useradd -m -d /home/charlotte-jump -s /bin/bash charlotte-jump + +# Disable password authentication +sudo sed -i 's/PasswordAuthentication.*/PasswordAuthentication no/' /etc/ssh/sshd_config + +# Create SSH directory structure with proper permissions +mkdir -p /home/charlotte-jump/.ssh +chmod 700 /home/charlotte-jump/.ssh + +# Add the public key to authorized_keys +echo "ssh-rsa AAAAB3N...your-public-key..." >> /home/charlotte-jump/.ssh/authorized_keys + +# Set proper permissions and ownership +chmod 600 /home/charlotte-jump/.ssh/authorized_keys +chown -R charlotte-jump:charlotte-jump /home/charlotte-jump/.ssh + +# Restart SSH service +systemctl restart sshd +``` + +### Wazuh Agent Installation +```bash +sudo WAZUH_MANAGER='172.16.200.10' WAZUH_AGENT_GROUP='linux' WAZUH_AGENT_NAME='jump-charlotte' rpm -ihv wazuh-agent-4.7.3-1.x86_64.rpm +sudo systemctl daemon-reload +sudo systemctl enable wazuh-agent +sudo systemctl start wazuh-agent +``` diff --git a/net-sec-controls-sec350/machines/MGMT01.md b/net-sec-controls-sec350/machines/MGMT01.md new file mode 100644 index 0000000..b8df2f0 --- /dev/null +++ b/net-sec-controls-sec350/machines/MGMT01.md @@ -0,0 +1,27 @@ +# MGMT01 Configuration + +## Network Configuration +- Configure static IP via network manager: + - IP Address: `172.16.150.10/24` + - Gateway & DNS: `172.16.150.2` + - Network: LAN + +## Chrome Remote Desktop Setup +1. Open Chrome and sign in with charlotte.croce@mymail.champlain.edu +2. Enable sync if prompted +3. Go to remotedesktop.google.com and install the app +4. On your main host (laptop): + - Go to https://g.co/crd/headless + - Download and install the Chrome Remote Desktop package + - For dependency issues: + ``` + sudo apt install libutempter0 xbase-clients xserver-xorg-video-dummy xvfb + sudo dpkg -i google-chrome-stable_current_amd64 + ``` +5. Follow the setup prompts and create a PIN +6. Log out of the remote computer before attempting to connect + +## Notes +- With current firewall configs, this machine should be able to access: + - SSH to systems in the DMZ (port 22) + - HTTPS access to wazuh server (port 443) diff --git a/net-sec-controls-sec350/machines/MGMT02.md b/net-sec-controls-sec350/machines/MGMT02.md new file mode 100644 index 0000000..16fa19f --- /dev/null +++ b/net-sec-controls-sec350/machines/MGMT02.md @@ -0,0 +1,7 @@ +# MGMT02 Configuration + +## Network Configuration +- Configure static IP: + - IP Address: `172.16.200.11/28` + - Gateway & DNS: `172.16.200.2` + - Network: MGMT diff --git a/net-sec-controls-sec350/machines/NGINX01.md b/net-sec-controls-sec350/machines/NGINX01.md new file mode 100644 index 0000000..21217a1 --- /dev/null +++ b/net-sec-controls-sec350/machines/NGINX01.md @@ -0,0 +1,35 @@ +# NGINX01 Configuration +## Basic Setup +- Set hostname to `nginx01-charlotte` +- Add sudo user `charlotte` + +- Set network via nmtui: + - IP Address: `172.16.50.3/29` + - Gateway & DNS: `172.16.50.2` + - Network adapter: DMZ + +## Install and Configure NGINX +```bash +# Install NGINX +sudo apt update +sudo apt install nginx -y +sudo systemctl enable nginx +sudo systemctl start nginx + +# Create custom index page +echo "

NGINX01 - Charlotte Croce

" | sudo tee /var/www/html/index.html +``` + +* Remember to add firewall and port forwarding rule for this new IP! +* Also, add firewall-cmd rules if applicable + +## Install Wazuh Agent +```bash +# Download and install Wazuh agent +curl -o wazuh-agent-4.7.5-1.amd64.deb https://packages.wazuh.com/4.x/apt/pool/main/w/wazuh-agent/wazuh-agent-4.7.5-1.amd64.deb && sudo WAZUH_MANAGER='172.16.200.10' WAZUH_AGENT_GROUP='linux' WAZUH_AGENT_NAME='nginx01-charlotte' dpkg -i wazuh-agent-4.7.5-1.amd64.deb + +# Start the agent +sudo systemctl daemon-reload +sudo systemctl enable wazuh-agent +sudo systemctl start wazuh-agent +``` diff --git a/net-sec-controls-sec350/machines/RW01.md b/net-sec-controls-sec350/machines/RW01.md new file mode 100644 index 0000000..db33006 --- /dev/null +++ b/net-sec-controls-sec350/machines/RW01.md @@ -0,0 +1,37 @@ +# RW01 Configuration + +## Basic Setup +- Set hostname to `rw01-charlotte` +- Add sudo user `charlotte:password` +- IP Address: `10.0.17.51/24` +- Gateway & DNS: `10.0.17.2` + +## Static Route for DMZ Access +```bash +sudo ip route add 172.16.50.0/29 via 10.0.17.151 +sudo systemctl restart NetworkManager +traceroute 172.16.50.3 +``` + +## Rsyslog Configuration for High Precision Timestamps +1. Edit `/etc/rsyslog.conf` +2. Comment out this line to enable high precision timestamps: + ``` + # $ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat + ``` +3. Restart rsyslog: + ```bash + sudo systemctl restart rsyslog + ``` + +## SSH Key Creation for Jump Server Access +Generate a dedicated SSH key for jump server access: +```bash +ssh-keygen -t rsa -b 4096 -C "ssh to jump" +# Use filename: jump-charlotte +# Add a passphrase +``` +To connect to the jump server using this key: +```bash +ssh -i ~/.ssh/jump-charlotte charlotte-jump@172.16.50.4 +``` diff --git a/net-sec-controls-sec350/machines/TRAVELER.md b/net-sec-controls-sec350/machines/TRAVELER.md new file mode 100644 index 0000000..b265be6 --- /dev/null +++ b/net-sec-controls-sec350/machines/TRAVELER.md @@ -0,0 +1,24 @@ +# TRAVELER Configuration +Windows machine to replace RW01 +## Network Configuration +- System is on WAN network +- IP address: `10.0.17.51/24` +- Default gateway: `10.0.17.2` +- DNS server: `10.0.17.2` + +## SSH Key Creation for Jump Server Access +Generate SSH keys using PowerShell: +```bash +# Generate new SSH key +ssh-keygen -t rsa -b 4096 -C "traveler to jump" +# Use filename: jump-charlotte +# Add a passphrase +``` +To connect to the jump server: +```powershell +ssh -i C:\Users\username\.ssh\jump-charlotte charlotte-jump@10.0.17.151 +``` + +Web Access +Can access nginx01 via `http://10.0.17.151:80` (port forwarded through edge-01) + diff --git a/net-sec-controls-sec350/machines/WAZUH.md b/net-sec-controls-sec350/machines/WAZUH.md new file mode 100644 index 0000000..b05bf90 --- /dev/null +++ b/net-sec-controls-sec350/machines/WAZUH.md @@ -0,0 +1,69 @@ +# Wazuh Server Configuration + +## Network Configuration +- Set hostname: `sudo hostnamectl hostname wazuh-charlotte` +- Configure static IP with netplan by editing `/etc/netplan/00-installer-config.yaml`: + ```yaml + network: + ethernets: + ens160: + addresses: + - 172.16.200.10/28 + nameservers: + addresses: [172.16.200.2] + routes: + - to: default + via: 172.16.200.2 + version: 2 + ``` +- Apply netplan configuration: + ``` + sudo netplan apply + ``` + +## Wazuh Installation +> **IMPORTANT**: Take a snapshot before installation + +Run the single-node installation command: +``` +curl -sO https://packages.wazuh.com/4.7/wazuh-install.sh && sudo bash ./wazuh-install.sh -a -i +``` +> Note: The `-i` flag ignores minimum requirements of 2 CPU and 4 GB RAM + +**IMPORTANT**: Save the auto-generated password shown after installation, you will need it later. + +## Accessing the Wazuh Dashboard +- Try accessing the dashboard at: http://172.16.200.10/app/login +- Login with the auto-generated credentials + +## Wazuh Agent Management +1. Create a new agent group: + - Wazuh dropdown > Management > Groups > Create a new group called "linux" + +2. Deploy a new agent: + - Wazuh dropdown > Agents > Deploy a new agent + - Configuration options: + - OS: Redhat/CentOS + - Version: CentOS 6 or higher (works on Rocky 8) + - Architecture: x86_64 + - Server IP: 172.16.200.10 + - Agent Group: Linux + +3. The web interface will generate an installation command for your agents + +## Firewall Requirements +Ensure these ports are open: +- **1514/TCP** for agent communication +- **1515/TCP** for enrollment via automatic agent request +- **55000/TCP** for enrollment via Wazuh server API + +## Agent Directory Structure +Wazuh agent files are stored in `/var/ossec/`. Key directories include: +- `/var/ossec/etc/` - Configuration files + - `/var/ossec/etc/ossec.conf` - agent IP settings +- `/var/ossec/logs/` - Log files +- `/var/ossec/queue/` - Communication queue +- `/var/ossec/agentless/` - Agentless monitoring + +## Viewing Security Events +Dropdown > Modules > Security Events diff --git a/net-sec-controls-sec350/machines/WEB01.md b/net-sec-controls-sec350/machines/WEB01.md new file mode 100644 index 0000000..cf31869 --- /dev/null +++ b/net-sec-controls-sec350/machines/WEB01.md @@ -0,0 +1,104 @@ +# WEB01 Configuration + +## Basic Setup +- Set hostname to `web01-charlotte` +- Add sudo user `charlotte:password` +- Set network via nmtui: + - IP Address: `172.16.50.3/29` + - Gateway & DNS: `172.16.50.2` + - Network adapter: DMZ + +## Install and Configure HTTPD +``` +# Install apache web server +sudo yum install httpd +sudo systemctl enable httpd +sudo systemctl start httpd + +# If you need to edit the main config file: +sudo vi /etc/httpd/conf/httpd.conf +``` + +## Rsyslog Configuration + +### Install rsyslog (if not installed) +``` +sudo yum install rsyslog +``` + +### Configure Rsyslog for High Precision Timestamps +Edit `/etc/rsyslog.conf` and add these lines: +``` +$ActionFileDefaultTemplate RSYSLOG_SyslogProtocol23Format +template(name="BetterTiming" type="string" string="%timestamp:::date-rfc3339% %HOSTNAME% %syslogtag%%msg%\n") +``` +Note: ModSecurity will prevent dangerous commands like cat /etc/passwd while allowing safe commands like whoami and /sbin/ifconfig. +Apply the template to the desired log file: +``` +# Example: Add ;BetterTiming suffix to a log destination +*.info;mail.none;authpriv.none;cron.none /var/log/messages;BetterTiming +``` + +### Configure Log Forwarding (when log01 is active) +Create a file at `/etc/rsyslog.d/sec350.conf` with these contents: +``` +# For general logging +user.notice @172.16.50.5 + +# For authentication logging +authpriv.* @172.16.50.5 +``` + +Restart rsyslog: +``` +sudo systemctl restart rsyslog +``` + +## Install Wazuh Agent +``` +# Download and install Wazuh agent +curl -o wazuh-agent-4.7.5-1.x86_64.rpm https://packages.wazuh.com/4.x/yum/wazuh-agent-4.7.5-1.x86_64.rpm && sudo WAZUH_MANAGER='172.16.200.10' WAZUH_AGENT_GROUP='linux' WAZUH_AGENT_NAME='web01-charlotte' rpm -ihv wazuh-agent-4.7.5-1.x86_64.rpm + +# Start the agent +sudo systemctl daemon-reload +sudo systemctl enable wazuh-agent +sudo systemctl start wazuh-agent +``` + +## CentOS Repo Fix (if needed) +``` +sudo sed -i s/mirror.centos.org/vault.centos.org/g /etc/yum.repos.d/CentOS-*.repo +sudo sed -i s/^#.*baseurl=http/baseurl=http/g /etc/yum.repos.d/CentOS-*.repo +sudo sed -i s/^mirrorlist=http/#mirrorlist=http/g /etc/yum.repos.d/CentOS-*.repo +``` + + +## Web Application Firewall (ModSecurity) +Install ModSecurity and PHP: +```bash +sudo yum install mod_security mod_security_crs php php-common php-opcache php-cli php-gd php-curl php-mysqlnd -y +``` + +## Create Test PHP Webshell +Create `/var/www/html/shell.php` with the following content: +``` + + + +
+ + +
+
+&1');
+    }
+?>
+
+ + +``` +> [!Note] +> ModSecurity will prevent dangerous commands like `cat /etc/passwd` while allowing safe commands like `whoami` and `/sbin/ifconfig`. diff --git a/net-sec-controls-sec350/machines/WKS01.md b/net-sec-controls-sec350/machines/WKS01.md new file mode 100644 index 0000000..81638fe --- /dev/null +++ b/net-sec-controls-sec350/machines/WKS01.md @@ -0,0 +1,10 @@ +# WKS01 Configuration + +## Network Configuration +- Configure static IP via network manager: + - IP Address: `172.16.150.50/24` + - Gateway & DNS: `172.16.150.2` + - Network: LAN + +## Notes +- This workstation has HTTP access to web01 in the DMZ through firewall rules diff --git a/net-sec-controls-sec350/osquery_project/01_research.md b/net-sec-controls-sec350/osquery_project/01_research.md new file mode 100644 index 0000000..0f3d18f --- /dev/null +++ b/net-sec-controls-sec350/osquery_project/01_research.md @@ -0,0 +1,27 @@ +|[HOME](README.md)|[RESEARCH](01_research.md)|[INSTALLATION](02_install_rocky.md)|[CLIENT APP](03_client_app.md)|[INTEGRATION](04_wazuh_integration.md)|[DEMONSTRATION](05_demonstration.md)|[CONCLUSION](06_conclusion.md)| +|-|-|-|-|-|-|-| + +# Research +Osquery is an open-source OS instrumentation framework that uses SQL-like syntax to query the OS as if it were a relational database. It was created by Facebook(Meta) in 2014. + +## Features +- **Cross-platform**: macOS, Linux, FreeBSD, and Windows +- **Data collection**: running processes, user logins, kernel modules, network connections, browser plugins, hardware events, file hashes, and more +- **SQL-based queries**: Users can write SQL queries to explore data across all operating systems and infrastructure +- **Query packs**: Pre-built collections of queries for specific tasks like incident response, vulnerability management, or compliance monitoring + +## Components +1. [**Osqueryi**](03_client_app.md): An interactive console shell for running ad-hoc queries and exploring the system +2. [**Osqueryd**](02_install_rocky.md): A daemon that schedules queries and monitors system changes + +> [!Warning] +> Osquery generates approximately 110MB of data per endpoint per day. This requires careful consideration of storage and management, especially for large-scale deployments. + +Sources: +- https://www.uptycs.com/blog/threat-research-report-team/osquery-guide +- https://rearc.io/blog/osquery-introduction +- https://www.rapid7.com/blog/post/2016/05/09/introduction-to-osquery-for-threat-detection-dfir/ + +___ +|[<<<<](README.md)|[>>>>](02_install_rocky.md)| +|-|-| diff --git a/net-sec-controls-sec350/osquery_project/02_install_rocky.md b/net-sec-controls-sec350/osquery_project/02_install_rocky.md new file mode 100644 index 0000000..267e451 --- /dev/null +++ b/net-sec-controls-sec350/osquery_project/02_install_rocky.md @@ -0,0 +1,54 @@ +|[HOME](README.md)|[RESEARCH](01_research.md)|[INSTALLATION](02_install_rocky.md)|[CLIENT APP](03_client_app.md)|[INTEGRATION](04_wazuh_integration.md)|[DEMONSTRATION](05_demonstration.md)|[CONCLUSION](06_conclusion.md)| +|-|-|-|-|-|-|-| + +# Install osquery on Rocky Linux (web01) + +## Installation +### DMZ-to-WAN temporary firewall rule +Add a temporary rule for software updates that we either delete, disable or discard when complete +```bash +set firewall name DMZ-to-WAN rule 999 action accept +set firewall name DMZ-to-WAN rule 999 source address 172.16.50.3 +``` +### Install via yum repository +- (current version: 15.5.0) -- [source](https://osquery.io/downloads/official/5.15.0) +```bash +curl -L https://pkg.osquery.io/rpm/GPG | sudo tee /etc/pki/rpm-gpg/RPM-GPG-KEY-osquery +sudo yum install yum-utils -y +sudo yum-config-manager --add-repo https://pkg.osquery.io/rpm/osquery-s3-rpm.repo +sudo yum-config-manager --enable osquery-s3-rpm-repo +sudo yum install osquery -y +``` +## Configuration +> [!Warning] +> Linux systems running journald will collect logging data originating from the kernel audit subsystem (something that osquery enables) from several sources, including audit records. To avoid performance problems on busy boxes (specially when osquery event tables are enabled), it is recommended to mask audit logs from entering the journal with the following command +> ```bash +> systemctl mask --now systemd-journald-audit.socket +> ``` +> -- [source](https://osquery.readthedocs.io/en/latest/installation/install-linux/) + +The `/etc/init.d/osqueryd` script does not automatically start the daemon until a configuration file is created. This is the command to copy the existing example config file into your working config files directory, this file may need further configuration. +```bash +sudo cp /opt/osquery/share/osquery/osquery.example.conf /etc/osquery/osquery.conf +``` + +## Running osquery +### Standalone/Client App (osqueryi) +To start a standalone osquery use: `osqueryi`. This does not need an osquery server or service. [osqueryi page](03_client_app.md) + +### Daemon Service (osqueryd) +```bash +sudo systemctl enable osqueryd +sudo systemctl start osqueryd +``` + +> [!Note] +> The interactive shell and daemon do NOT communicate! + + + +___ +Source: https://documentation.wazuh.com/current/user-manual/capabilities/system-inventory/osquery.html + +|[<<<<](01_research.md)|[>>>>](03_client_app.md)| +|-|-| diff --git a/net-sec-controls-sec350/osquery_project/03_client_app.md b/net-sec-controls-sec350/osquery_project/03_client_app.md new file mode 100644 index 0000000..8f6f289 --- /dev/null +++ b/net-sec-controls-sec350/osquery_project/03_client_app.md @@ -0,0 +1,59 @@ +|[HOME](README.md)|[RESEARCH](01_research.md)|[INSTALLATION](02_install_rocky.md)|[CLIENT APP](03_client_app.md)|[INTEGRATION](04_wazuh_integration.md)|[DEMONSTRATION](05_demonstration.md)|[CONCLUSION](06_conclusion.md)| +|-|-|-|-|-|-|-| + +# osquery Client Application (osqueryi) +`osqueryi` is an interactive shell for osquery that uses SQL-like queries to gather system information. It allows you to query various aspects of an operating system as if they were tables in a database. + +## Common queries: +Inspect system processes: +```sql +osquery> SELECT name, path, pid FROM processes WHERE name = 'httpd'; ++-------+-----------------+-------+ +| name | path | pid | ++-------+-----------------+-------+ +| httpd | /usr/sbin/httpd | 82243 | +| httpd | /usr/sbin/httpd | 86173 | +| httpd | /usr/sbin/httpd | 86174 | +| httpd | /usr/sbin/httpd | 86175 | +| httpd | /usr/sbin/httpd | 86176 | ++-------+-----------------+-------+ +``` +List installed packages: +```sql +osquery> SELECT name, version FROM rpm_packages; ++-------------------------------+------------+ +| name | version | ++-------------------------------+------------+ +| NetworkManager | 1.36.0 | +| NetworkManager-config-server | 1.36.0 | +| NetworkManager-libnm | 1.36.0 | +| NetworkManager-team | 1.36.0 | +| NetworkManager-tui | 1.36.0 | +| acl | 2.2.53 | +| adcli | 0.8.2 | +| alsa-sof-firmware | 1.9.3 | +| apr | 1.6.3 | +| apr-util | 1.6.1 | +... +``` +Check listening network ports: +```sql +osquery> SELECT pid, address, port FROM listening_ports; ++-------+-----------+-------+ +| pid | address | port | ++-------+-----------+-------+ +| 1101 | 0.0.0.0 | 22 | +| 86176 | :: | 80 | +| 1101 | :: | 22 | +| 34468 | 0.0.0.0 | 51361 | +| 942 | 127.0.0.1 | 323 | +| 942 | ::1 | 323 | +| 1068 | :: | 58 | +| 924 | | 0 | +| 924 | | 0 | +... +``` + +___ +|[<<<<](02_install_rocky.md)|[>>>>](04_wazuh_integration.md)| +|-|-| diff --git a/net-sec-controls-sec350/osquery_project/04_wazuh_integration.md b/net-sec-controls-sec350/osquery_project/04_wazuh_integration.md new file mode 100644 index 0000000..21a0948 --- /dev/null +++ b/net-sec-controls-sec350/osquery_project/04_wazuh_integration.md @@ -0,0 +1,107 @@ +|[HOME](README.md)|[RESEARCH](01_research.md)|[INSTALLATION](02_install_rocky.md)|[CLIENT APP](03_client_app.md)|[INTEGRATION](04_wazuh_integration.md)|[DEMONSTRATION](05_demonstration.md)|[CONCLUSION](06_conclusion.md)| +|-|-|-|-|-|-|-| + +# Wazuh Integration + +## Requirements +- Wazuh manager installed and configured on the wazuh server +- Wazuh agent installed and connected on WEB01 +- osquery already installed on WEB01 ([installation guide](02_install_rocky.md)) +- root privileges + +## Configure osquery on web01 +### on WEB01 +- create osquery configuration file. if already created with defaults, edit it +```json +> sudo nano /etc/osquery/osquery.conf +{ + "options": { + "logger_path": "/var/log/osquery", + "disable_logging": "false", + "schedule_splay_percent": "10", + "utc": "true" + }, + "schedule": { + "system_info": { + "query": "SELECT hostname, cpu_brand, physical_memory FROM system_info;", + "interval": 300 + }, + "processes": { + "query": "SELECT pid, name, path, cmdline FROM processes;", + "interval": 300 + }, + "logged_in_users": { + "query": "SELECT user, host, time FROM logged_in_users;", + "interval": 300 + }, + "firewall_status": { + "query": "SELECT * FROM shell WHERE command = 'firewall-cmd --state';", + "interval": 300 + } + }, +... +``` + +- create log directories with correct permissions for storing osquery results +```bash +sudo mkdir -p /var/log/osquery +sudo chown -R root:root /var/log/osquery +sudo chmod -R 755 /var/log/osquery +``` + +- restart osqueryd +```bash +sudo systemctl restart osqueryd +sudo systemctl status osqueryd +``` + +## Configure WEB01 -> Wazuh integration +### On WEB01 +- configure Wazuh agent to monitor osquery logs +```xml +> sudo nano /var/ossec/etc/ossec.conf + +# Add these blocks inside the section +# make sure this wodle is NOT disabled, as this service is disabled by default + + + no + yes + /var/log/osquery/osqueryd.results.log + /etc/osquery/osquery.conf + yes + + + + + json + /var/log/osquery/osqueryd.results.log + +``` + +- restart wazuh agent +```bash +sudo systemctl restart wazuh-agent +sudo systemctl status wazuh-agent +``` + +## Validation +### on WEB01 +- Run a manual query to generate an immediate log entry +``` +sudo osqueryi --json "SELECT * FROM processes LIMIT 5;" > /var/log/osquery/osqueryd.results.log +``` +- Check if Wazuh detected it +``` +sudo tail -f /var/ossec/logs/ossec.log +``` +### on Wazuh Server +- Go to Modules Menu -> Security Events -> Events +- In left panel, add rule.groups: osquery +![image](../../assets/54a8264b-ffac-4f98-be7d-5d1abce24233.png) + + +___ +|[<<<<](03_client_app.md)|[>>>>](05_demonstration.md)| +|-|-| + diff --git a/net-sec-controls-sec350/osquery_project/05_demonstration.md b/net-sec-controls-sec350/osquery_project/05_demonstration.md new file mode 100644 index 0000000..8c33754 --- /dev/null +++ b/net-sec-controls-sec350/osquery_project/05_demonstration.md @@ -0,0 +1,7 @@ +|[HOME](https://git.charlotte.sh/lotte/ChamplainTechJournals/src/branch/main/net-sec-controls-sec350/osquery_project/README.md)|[RESEARCH](https://git.charlotte.sh/lotte/ChamplainTechJournals/src/branch/main/net-sec-controls-sec350/osquery_project/01_research.md)|[INSTALLATION](https://git.charlotte.sh/lotte/ChamplainTechJournals/src/branch/main/net-sec-controls-sec350/osquery_project/02_install_rocky.md)|[CLIENT APP](https://git.charlotte.sh/lotte/ChamplainTechJournals/src/branch/main/net-sec-controls-sec350/osquery_project/03_client_app.md)|[INTEGRATION](https://git.charlotte.sh/lotte/ChamplainTechJournals/src/branch/main/net-sec-controls-sec350/osquery_project/04_wazuh_integration.md)|[DEMONSTRATION](https://git.charlotte.sh/lotte/ChamplainTechJournals/src/branch/main/net-sec-controls-sec350/osquery_project/05_demonstration.md)|[CONCLUSION](https://git.charlotte.sh/lotte/ChamplainTechJournals/src/branch/main/net-sec-controls-sec350/osquery_project/06_conclusion.md)| +|-|-|-|-|-|-|-| + +# Demonstration +___ +|[<<<<](04_wazuh_integration.md)|[>>>>](06_conclusion.md)| +|-|-| diff --git a/net-sec-controls-sec350/osquery_project/06_conclusion.md b/net-sec-controls-sec350/osquery_project/06_conclusion.md new file mode 100644 index 0000000..8cbae67 --- /dev/null +++ b/net-sec-controls-sec350/osquery_project/06_conclusion.md @@ -0,0 +1,19 @@ +|[HOME](README.md)|[RESEARCH](01_research.md)|[INSTALLATION](02_install_rocky.md)|[CLIENT APP](03_client_app.md)|[INTEGRATION](04_wazuh_integration.md)|[DEMONSTRATION](05_demonstration.md)|[CONCLUSION](06_conclusion.md)| +|-|-|-|-|-|-|-| +# Conclusion + +## Pros +- open source +- lightweight +- works on Linux, macOS, and Windows +## Cons +- stores current system state, which means it doesn't store historical data + + +## Overview + +In conclusion, the OSQuery project demonstrates the potential of integrating OSQuery with Wazuh for enhanced security monitoring. OSQuery provides a powerful tool for querying and monitoring system data, while Wazuh offers robust endpoint detection and response capabilities. The integration of these tools allows for real-time event detection and analysis, offering significant benefits in terms of security visibility and incident response. However, considerations regarding complexity and resource requirements are important when implementing such a system. Overall, the integration of OSQuery with Wazuh presents a promising approach to strengthening corporate security infrastructure. + +___ +|[<<<<](05_demonstration.md)|| +|-|-| diff --git a/net-sec-controls-sec350/osquery_project/README.md b/net-sec-controls-sec350/osquery_project/README.md new file mode 100644 index 0000000..9e9cd52 --- /dev/null +++ b/net-sec-controls-sec350/osquery_project/README.md @@ -0,0 +1,23 @@ +|[HOME](README.md)|[RESEARCH](01_research.md)|[INSTALLATION](02_install_rocky.md)|[CLIENT APP](03_client_app.md)|[INTEGRATION](04_wazuh_integration.md)|[DEMONSTRATION](05_demonstration.md)|[CONCLUSION](06_conclusion.md)| +|-|-|-|-|-|-|-| + +Charlotte Croce, Andrei Gorlitsky, Benjamin Tyler + +# Project 1 -OSQuery + +🚀 Your security engineering technical lead has asked you to investigate a potential security tool called [OSQuery](https://github.com/osquery/osquery). They have asked that you be prepared to demonstrate the application itself and its integration into the corporate EDR platform (wazuh). You are expected to demo your results to the full security engineering team in one week. + +## Demonstration Video +Google Drive link: https://drive.google.com/file/d/1TmDQrPufHJVOyXyVaR0a5f4StchSyOn2/view?usp=drive_link + +## Documentation Contents +- [RESEARCH:](01_research.md) Conduct high level research on OSQuery and explain what it does at a high level +- [INSTALLATION:](02_install_rocky.md) Install OSQuery on either web01 (rocky) or wks01 (windows 10) +- [CLIENT APP:](03_client_app.md) Investigate and demonstrate some of the features of the OSQuery client application +- [INTEGRATION:](04_wazuh_integration.md) Integrate OSQuery with Wazuh +- [DEMONSTRATION:](05_demonstration.md) Develop an end to end demonstration that shows the triggering of an event that is picked up by OSQuery and how that event eventually makes it to Wazuh. +- [CONCLUSION:](06_conclusion.md) Conclude by discussing any pros and cons of this tool and integration. + +___ +||[>>>>](01_research.md)| +|-|-| diff --git a/net-sec-controls-sec350/rsyslog.md b/net-sec-controls-sec350/rsyslog.md new file mode 100644 index 0000000..9e5e476 --- /dev/null +++ b/net-sec-controls-sec350/rsyslog.md @@ -0,0 +1,38 @@ +# rsyslog configuration +an open-source software used on linux computer systems for forwarding log messages through a network. \ +`sudo apt/yum install rsyslog` + +## server +### open ports 514 on server +``` +sudo firewall-cmd --add-port=514/tcp --permament +sudo firewall-cmd --add-port=514/udp --permament +sudo firewall-cmd --reload +``` + +### enable log input modules +the `/etc/rsyslog.conf` file needs to be modified to receive syslog messages over ports 514 tcp and udp. Uncomment the appropriate lines (see below) and restart the rsyslog service. \ +![image](../assets/48994d9b-0f17-4626-ab9d-985d37c5e506.png) + +### monitor for incoming logs +- `tail -f /var/log/messages` + + +## client +### configure log forwarding to server +- rsyslog needs to be installed on client as well: `sudo yum install rsyslog` +- create the following file: `/etc/rsyslog.d/sec350.conf`, add the line `user.notice @172.16.50.5`, and restart rsyslog +![image](../assets/143d58a5-5713-4425-b1d5-d8f9dcf63cf0.png) + +> **_NOTE:_** the line in sec350.conf means: \ +> user = syslog facility \ +> notice = syslog priority \ +> @=UDP, @@ means TCP, so we are only going to send UDP \ +> 172.16.50.5 = Remote Syslog Server + +#### loggin authpriv messages on linux systems +![image](../assets/77c2b1f5-6aa2-4e76-8db6-59feb31cb4fb.png) + + +### create test log +- `logger -t test TESTLOG123` diff --git a/net-sec-controls-sec350/vyos.md b/net-sec-controls-sec350/vyos.md new file mode 100644 index 0000000..3c7dd45 --- /dev/null +++ b/net-sec-controls-sec350/vyos.md @@ -0,0 +1,63 @@ +# VyOS +an open source networking OS based on Debian \ +https://docs.vyos.io/en/sagitta/ + +## Overview +- VyOS has two modes: operational and configuration mode +- The operational mode is used to view the system status and run commands (command prompt displays `$`) +- the configuration mode is used to modify the system configuration (command prompt displays `#`) + +## Commands +### Basics +- enter configuration mode from operational mode: `configure` +- exit configuration mode: `exit` +- commit current set of changes `commit` +- save current changes: `save` + - `commit`, followed by `save` will save configuration changes + +### Change Password +``` +set system login user vyos authentication plaintext-password [password] +``` + +### Set Hostname +``` +set system host-name fw01-charlotte +``` + +### Interfaces +- set IP: `set interfaces ethernet ethX address 172.16.50.X./24` +- add description: `set interfaces ethernet ethX description SEC350-WAN` +- `show interfaces` + +### Gateway and DNS Server +- create default route (gateway): `set protocols static route 0.0.0.0/0 next-hop 10.0.17.2` +- set DNS server: `set system name-server 10.0.17.2` + + +### NAT +``` +set nat source rule 10 description "NAT FROM DMZ to WAN" +set nat source rule 10 outbound-interface eth0 +set nat source rule 10 source address 172.16.50.0/29 +set nat source rule 10 translation address masquerade +show nat source translations +``` + +### DNS Forwarding +``` +set service dns forwarding listen-address 172.16.50.2 +set service dns forwarding allow-from 172.16.50.0/29 +set service dns forwarding system +``` + +### Forward authentication events from vyos to a remote syslog server +``` +set system syslog host 172.16.50.5 facility authpriv level info +``` + + +### Export configuration +``` +show configuration commands | grep -v "syslog global\|ntp\|login\|console\|config\|hw-id\|loopback\|conntrack" +``` diff --git a/net-sec-controls-sec350/wazuh.md b/net-sec-controls-sec350/wazuh.md new file mode 100644 index 0000000..280bcf5 --- /dev/null +++ b/net-sec-controls-sec350/wazuh.md @@ -0,0 +1,28 @@ +# Wazuh + +## Installing Server +- run the following command: `curl -sO https://packages.wazuh.com/4.7/wazuh-install.sh && sudo bash ./wazuh-install.sh -a -i` +- remember to save the auto-generated password + +### Ports to open on firewall +- **1514/TCP** for agent communication. +- **1515/TCP** for enrollment via automatic agent request. +- **55000/TCP** for enrollment via Wazuh server API. + +## Installing Agents +- Wazuh dropdown > Agents > enter agent configurations +- run the generated command on the remote system to install the agent: +- start agent service: +``` +sudo systemctl daemon-reload +sudo systemctl enable wazuh-agent +sudo systemctl start wazuh-agent +``` + +## Agent directory structure +Wazuh agent files are stored in /var/ossec/. Key directories include: +- `/var/ossec/etc/` - Configuration files + - `/var/ossec/etc/ossec.conf` - agent IP settings +- `/var/ossec/logs/` - Log files +- `/var/ossec/queue/` - Communication queue +- `/var/ossec/agentless/` - Agentless monitoring diff --git a/python-csi160/json-api-lab/main.py b/python-csi160/json-api-lab/main.py new file mode 100644 index 0000000..0bfea18 --- /dev/null +++ b/python-csi160/json-api-lab/main.py @@ -0,0 +1,48 @@ +# 4/4/2025 - Charlotte Croce +# JSON API LAB +# +# this program uses the Coinbase API to get a dictionary of currencies and their prices +# the user can search for a currency by symbol and get its name and price +# +import requests + +API_URL = "https://api.coinbase.com/v2/currencies" +response = requests.get(API_URL) + +# Parse the JSON response +response_data = response.json() + +# create dictionary with currency symbol as key and name as value +currency_dict = {currency['id']: currency['name'] for currency in response_data['data']} + +# not included in the dictionary because it is many seperate requests +# and takes a while to process +def get_currency_price(symbol): + price_url = f"https://api.coinbase.com/v2/prices/{symbol}-USD/spot" + try: + price_response = requests.get(price_url) + price_data = price_response.json() + return price_data['data']['amount'] + except (requests.exceptions.RequestException, KeyError, ValueError): + return "Price unavailable" + + +def display_list(): + # ':<10' creates a 10 character wide column + print(f"{'Symbol':<10} {'Name':<10}") + for symbol, name in currency_dict.items(): + print(f"{symbol:<10} {name:<10}") + +while True: + # Prompt user for currency symbol + symbol = input("Enter currency symbol ('l' to list currencies')('q' to quit): ").upper() + if symbol == 'Q': + break + # if user enter's 'l' Display currencies as table + if symbol == 'L': + display_list() + # Check if symbol is in dictionary + if symbol in currency_dict: + print(f"\n{currency_dict[symbol]}\n1{symbol} = ${get_currency_price(symbol)}USD\n") + else: + print(f"{symbol} not found") diff --git a/python-csi160/json-api-lab/requirements.txt b/python-csi160/json-api-lab/requirements.txt new file mode 100644 index 0000000..663bd1f --- /dev/null +++ b/python-csi160/json-api-lab/requirements.txt @@ -0,0 +1 @@ +requests \ No newline at end of file diff --git a/python-csi160/midterm/part1.py b/python-csi160/midterm/part1.py new file mode 100644 index 0000000..fa4559c --- /dev/null +++ b/python-csi160/midterm/part1.py @@ -0,0 +1,14 @@ +""" +Do not use AI! You can schedule to try again if you have a bad grade! +Basic Function Write a function named exactly "calculate_discounted_price" which receives 2 parameters: price(float) +and discount(float) in percentage, and returns the final price after applying the discount. + +Example: +print(calculate_discounted_price(100, 10)) # Output: 90.0 +print(calculate_discounted_price(50, 50)) # Output: 25.0 +""" +def calculate_discounted_price(price, discount): + return price - (price * discount * .01) + +print(calculate_discounted_price(100,10)) +print(calculate_discounted_price(50,50)) \ No newline at end of file diff --git a/python-csi160/midterm/part10.py b/python-csi160/midterm/part10.py new file mode 100644 index 0000000..cf8d9f9 --- /dev/null +++ b/python-csi160/midterm/part10.py @@ -0,0 +1,62 @@ +''' +Do not use AI! You can schedule to try again if you have a bad grade! +This is a bonus question, and it might hard. It is not mandatory to solve it. You can skip it if you want. +Spiral Matrix is a matrix of size 'n x n' filled with numbers from 1 to (n*n) in a spiral order. +Write a function 'spiral_matrix' that receives an integer 'n' as parameter and returns a list of lists representing the spiral matrix. +Examples of Spiral Matrix: +n = 1 +[[1]] +n = 2 +[[1, 2], + [4, 3]] +n = 3 +[[1, 2, 3], + [8, 9, 4], + [7, 6, 5]] +n = 4 +[[1, 2, 3, 4], + [12, 13, 14, 5], + [11, 16, 15, 6], + [10, 9, 8, 7]] + +Example: +print(spiral_matrix(3)) +# Output: +[[1, 2, 3], [8, 9, 4], [7, 6, 5]] +''' + +def spiral_matrix(n): + # create an empty n x n matrix filled with zeros + matrix = [[0 for i in range(n)] for j in range(n)] + + counter = 1 + row = 0 + col = 0 + + for i in range(1, n*n): + while col < n - i: + matrix[row][col] = counter + counter += 1 + col += 1 + + while row < n - i: + matrix[row][col] = counter + counter += 1 + row += 1 + + while col > 0 + (i - 1): + matrix[row][col] = counter + counter += 1 + col -= 1 + + while row > 0 + i: + matrix[row][col] = counter + counter += 1 + row -= 1 + + matrix[row][col] = counter + return matrix + +print(spiral_matrix(5)) +# Output: +[[1, 2, 3], [8, 9, 4], [7, 6, 5]] \ No newline at end of file diff --git a/python-csi160/midterm/part2.py b/python-csi160/midterm/part2.py new file mode 100644 index 0000000..839f9f3 --- /dev/null +++ b/python-csi160/midterm/part2.py @@ -0,0 +1,15 @@ +''' +Do not use AI! You can schedule to try again if you have a bad grade! +Write a function named exactly 'divide_and_remainder' and receive a parameter 'num' and a base 'b' and returns a tuple +where: he first element is the result of integer division, and the second element is the remainder. + +Example: +print(divide_and_remainder(10, 3)) # Output: (3, 1) +print(divide_and_remainder(10, 2)) # Output: (5, 0) +''' + +def divide_and_remainder(num, b): + return (num // b, num % b) + +print(divide_and_remainder(10, 3)) # Output: (3, 1) +print(divide_and_remainder(10, 2)) # Output: (5, 0) \ No newline at end of file diff --git a/python-csi160/midterm/part3.py b/python-csi160/midterm/part3.py new file mode 100644 index 0000000..9971d08 --- /dev/null +++ b/python-csi160/midterm/part3.py @@ -0,0 +1,26 @@ +''' +Do not use AI! You can schedule to try again if you have a bad grade! +This question can be challenging, so leave it to the end if you are running out of time. +Lucas Sequence Write a function 'lucas' which receives an integer 'n' as parameter and returns the 'n-th' element of the + lucas sequence. The Lucas sequence is a series of numbers in which each number is the sum of the two preceding just + like fibonacci, but the first two numbers are 2 and 1, instead of 0 and 1. So the sequence goes like this: + 2, 1, 3, 4, 7, 11, 18, 29... + +Do not use recursion to solve this problem. + +Examples: +lucas(0) # returns 2 +lucas(1) # returns 1 +lucas(2) # returns 3 +lucas(5) # returns 11 +''' +def lucas(n): + lucas_numbers = [2, 1] + for i in range(2, n + 1): + lucas_numbers.append(lucas_numbers[i - 1] + lucas_numbers[i - 2]) + return lucas_numbers[n] + +print(lucas(0)) # returns 2 +print(lucas(1)) # returns 1 +print(lucas(2)) # returns 3 +print(lucas(5)) # returns 11 \ No newline at end of file diff --git a/python-csi160/midterm/part4.py b/python-csi160/midterm/part4.py new file mode 100644 index 0000000..24f1c88 --- /dev/null +++ b/python-csi160/midterm/part4.py @@ -0,0 +1,19 @@ +''' +Do not use AI! You can schedule to try again if you have a bad grade! +Write a function named exactly "last2" which receives a list of elements as parameter and then return the second element + from the end to the beginning of the list. If the list has less than two elements, the function should return None. + +Example: +print(last2(['red', 'blue', 'green', 'yellow'])) # Output: green +print(last2([0,1])) # Output: 0 +print(last2([0])) # Output: None +''' +def last2(lst): + if len(lst) < 2: + return None + else: + return lst[-2] + +print(last2(['red', 'blue', 'green', 'yellow'])) # Output: green +print(last2([0,1])) # Output: 0 +print(last2([0])) # Output: None \ No newline at end of file diff --git a/python-csi160/midterm/part5.py b/python-csi160/midterm/part5.py new file mode 100644 index 0000000..5876aee --- /dev/null +++ b/python-csi160/midterm/part5.py @@ -0,0 +1,22 @@ +''' +Do not use AI! You can schedule to try again if you have a bad grade! +Write a function named exactly "median" which receives a list of element as parameter and returns the median value of +the list. The median is the value separating the higher half from the lower half of a data sample. If the list has an +even number of elements, the function should return the average of the two middle elements. You should not modify the +original list, but you can sort in a copy of the list. + +Example: +median([1, 2, 3, 4, 5]) # returns: 3 +median([1, 2, 3, 4, 5, 6]) # returns: 3.5 +''' +def median(numbers): + sortedNums = sorted(numbers) + length = len(sortedNums) + mid = length // 2 + if length % 2 == 0: # even number-> avg of middle two + return (sortedNums[mid - 1] + sortedNums[mid]) / 2 + else: # odd number-> middle element + return sortedNums[mid] + +print(median([1, 3, 2, 4, 5])) # returns: 3 +print(median([1, 2, 3, 4, 5, 6])) # returns: 3.5 \ No newline at end of file diff --git a/python-csi160/midterm/part6.py b/python-csi160/midterm/part6.py new file mode 100644 index 0000000..e6647d0 --- /dev/null +++ b/python-csi160/midterm/part6.py @@ -0,0 +1,37 @@ +''' +Do not use AI! You can schedule to try again if you have a bad grade! +You are building a music playlist system. Write a function named 'manage_playlist' which receives 3 paramenters: a +list of song names, a new song name to be added to the end of the playlist, and a song name to be searched in the +playlist. It should return the index of the searched song in the updated playlist (or None if the song is not found). + +Example: +playlist = ['Dream On', 'Bohemian Rhapsody', 'Stairway to Heaven'] +print(manage_playlist(playlist, 'Hotel California', 'Bohemian Rhapsody')) # Output: 1 +print(playlist) # Output: ['Dream On', 'Bohemian Rhapsody', 'Stairway to Heaven', 'Hotel California'] + +playlist = ['Imagine', 'Confortably Numb'] +print(manage_playlist(playlist, 'Wish You Were Here', 'Wish You Were Here')) # Output: 2 +print(playlist) # Output: ['Imagine', 'Confortably Numb', 'Wish You Were Here'] + +playlist = ['Imagine', 'Confortably Numb'] +print(manage_playlist(playlist, 'Wish You Were Here', 'Smoking on the Water')) # Output: None +print(playlist) # Output: ['Imagine', 'Confortably Numb', 'Wish You Were Here'] +''' +def manage_playlist(playlist, new_song, search_song): + playlist.append(new_song) + for i in range(len(playlist)): + if playlist[i] == search_song: + return i + return None + +playlist = ['Dream On', 'Bohemian Rhapsody', 'Stairway to Heaven'] +print(manage_playlist(playlist, 'Hotel California', 'Bohemian Rhapsody')) # Output: 1 +print(playlist) # Output: ['Dream On', 'Bohemian Rhapsody', 'Stairway to Heaven', 'Hotel California'] + +playlist = ['Imagine', 'Confortably Numb'] +print(manage_playlist(playlist, 'Wish You Were Here', 'Wish You Were Here')) # Output: 2 +print(playlist) # Output: ['Imagine', 'Confortably Numb', 'Wish You Were Here'] + +playlist = ['Imagine', 'Confortably Numb'] +print(manage_playlist(playlist, 'Wish You Were Here', 'Smoking on the Water')) # Output: None +print(playlist) # Output: ['Imagine', 'Confortably Numb', 'Wish You Were Here'] \ No newline at end of file diff --git a/python-csi160/midterm/part7.py b/python-csi160/midterm/part7.py new file mode 100644 index 0000000..794d476 --- /dev/null +++ b/python-csi160/midterm/part7.py @@ -0,0 +1,24 @@ +''' +Do not use AI! You can schedule to try again if you have a bad grade! +Write a function named 'split_full_name' which receives a parameter 'full_name' with 2 or more surnames and returns a +tuple with the last name and the first name. The full name will be a string with the following format: +"first_name middle1 middle2 ... lastname" where middle1, middle2, ... are optional middle names and the last word is the + last name. The function should return a tuple with the last name and the first name. If the full name has only one + word, the function should return a tuple with the word as the last name and an empty string as the first name. + +Example: +print(split_full_name("John Doe")) # Output: ('Doe', 'John') +print(split_full_name("John Doe Smith")) # Output: ('Smith', 'John') +print(split_full_name("John")) # Output: ('John', '') +print(split_full_name("John Doe Smith Lee")) # Output: ('Lee', 'John') +''' +def split_full_name(full_name): + namelist = full_name.split(" ") + if len(namelist) < 2: + return (namelist[0], '') + return (namelist[-1], namelist[0]) + +print(split_full_name("John Doe")) # Output: ('Doe', 'John') +print(split_full_name("John Doe Smith")) # Output: ('Smith', 'John') +print(split_full_name("John")) # Output: ('John', '') +print(split_full_name("John Doe Smith Lee")) # Output: ('Lee', 'John') \ No newline at end of file diff --git a/python-csi160/midterm/part8.py b/python-csi160/midterm/part8.py new file mode 100644 index 0000000..6a7ea24 --- /dev/null +++ b/python-csi160/midterm/part8.py @@ -0,0 +1,21 @@ +''' +Do not use AI! You can schedule to try again if you have a bad grade! +Write a function named 'countdown' which receives a parameter 'n' and returns a list with the countdown from 'n' to 0 +both included. If 'n' is less than 0, the function should return an empty list. + +Example: +print(countdown(5)) # Output: [5, 4, 3, 2, 1, 0] +print(countdown(0)) # Output: [0] +print(countdown(-1)) # Output: [] +print(countdown(10)) # Output: [10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0] +''' +def countdown(n): + lst = [] + for i in range(n, -1, -1): + lst.append(i) + return lst + +print(countdown(5)) # Output: [5, 4, 3, 2, 1, 0] +print(countdown(0)) # Output: [0] +print(countdown(-1)) # Output: [] +print(countdown(10)) # Output: [10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0] \ No newline at end of file diff --git a/python-csi160/midterm/part9.py b/python-csi160/midterm/part9.py new file mode 100644 index 0000000..59c57dc --- /dev/null +++ b/python-csi160/midterm/part9.py @@ -0,0 +1,38 @@ +''' +Do not use AI! You can schedule to try again if you have a bad grade! +Write a functon named 'above_main_diagonal' which receives a square matrix as parameter and returns the sum of the +elements above the main diagonal. The main diagonal is the one that goes from the top-left to the bottom-right of the +matrix. A number is characterized as above the main diagonal if its row index is less than its column index. The matrix +will always have at least one element. + +Example: +matrix = [[1, 1, 1], + [1, 1, 1], + [1, 1, 1]] +print(above_main_diagonal(matrix)) # Output: 3. It will sum 1+1+1 + +matrix = [[1, 2, 3, 4], + [5, 6, 7, 8], + [9, 10, 11, 12], + [13, 14, 15, 16]] +print(above_main_diagonal(matrix)) # Output: 36. It will sum 2+3+4+7+8+12 +''' +def above_main_diagonal(matrix): + sum = 0 + for row in range(len(matrix)): + for col in range(len(matrix[0])): + if row < col: + sum += matrix[row][col] + return sum + + +matrix = [[1, 1, 1], + [1, 1, 1], + [1, 1, 1]] +print(above_main_diagonal(matrix)) # Output: 3. It will sum 1+1+1 + +matrix = [[1, 2, 3, 4], + [5, 6, 7, 8], + [9, 10, 11, 12], + [13, 14, 15, 16]] +print(above_main_diagonal(matrix)) # Output: 36. It will sum 2+3+4+7+8+12 \ No newline at end of file diff --git a/python-csi160/ollama/ollama.py b/python-csi160/ollama/ollama.py new file mode 100644 index 0000000..37456b1 --- /dev/null +++ b/python-csi160/ollama/ollama.py @@ -0,0 +1,17 @@ +# in a seperate terminal: +# ollama run gemma2 + +import requests + +prompt = "Why the sky is blue?" + +data = { + "model": "gemma2:2b", + "prompt": prompt, + "stream": False +} + +response = requests.post("http://localhost:11434/api/generate", json=data) +json_response = response.json() +message = json_response["response"] +print(message) \ No newline at end of file diff --git a/python-csi160/password-manager/password-manager.py b/python-csi160/password-manager/password-manager.py new file mode 100644 index 0000000..1f28187 --- /dev/null +++ b/python-csi160/password-manager/password-manager.py @@ -0,0 +1,389 @@ +import pickle +import sys +import random +import string + +# The password list - We start with it populated for testing purposes +entries = {'yahoo': {'username': 'johndoe', 'password': 'cus#u%S tu', 'url': 'https://www.yahoo.com'}, + 'google': {'username': 'johndoe', 'password': '`q$$( #tABCD^ %fu#*W t', 'url': 'https://www.google.com'}} + +# The password file name to store the data to +password_file_name = "PasswordFile.pickle" + +# The encryption key for the caesar cypher +encryption_key = 16 + +menu_text = """ +What would you like to do: +1. Open password file +2. Add an entry +3. Lookup an entry +4. Save password file +5. Quit program +6. Print dictionary for testing +7. Delete an entry +8. Edit an entry +Please enter a number (1-8)""" + +def password_encrypt(unencrypted_message, key): + """Returns an encrypted message using a caesar cypher + + :param unencryptedMessage (string) + :param key (int) The offset to be used for the caesar cypher + :return (string) The encrypted message + """ + result_string = '' + min_limit = 32 + max_limit = 126 + for character in unencrypted_message: + value = ord(character) - min_limit + key + value = value % (max_limit - min_limit + 1) + value = value + min_limit + result_string = result_string + chr(value) + return result_string + +def password_decrypt(encrypted_message, key): + """Returns a decrypted message. + :param encrypted_message (string): + :param key (int) The offset that was used to encrypt the message + :return (string): The decrypted message + """ + return password_encrypt(encrypted_message, -key) + +def load_password_file(): + """Loads a password file. The file must be in the same directory as the .py file + """ + global entries, encryption_key + try: + entries, encryption_key = pickle.load(open(password_file_name, "rb")) + print(f"Password file '{password_file_name}' loaded successfully!") + except FileNotFoundError: + print(f"File '{password_file_name}' not found. Starting with an empty dictionary.") + entries = {} + except Exception as e: + print(f"Error loading file: {e}") + +def save_password_file(): + """Saves a password file. The file will be created if it doesn't exist. + """ + try: + pickle.dump((entries, encryption_key), open(password_file_name, "wb")) + print(f"Password file '{password_file_name}' saved successfully!") + except Exception as e: + print(f"Error saving file: {e}") + +def generate_random_password(length=12): + """Generates a random password that meets complexity requirements. + + The generated password will: + - Be at least 8 characters long (default 12) + - Contain at least one uppercase letter + - Contain at least one lowercase letter + - Contain at least one digit + - Contain at least one special character + + :param length (int): Length of the password to generate (minimum 8) + :return (string): A randomly generated password meeting all requirements + """ + if length < 8: + length = 8 # Enforce minimum length + + # Define character sets + uppercase_letters = string.ascii_uppercase + lowercase_letters = string.ascii_lowercase + digits = string.digits + special_chars = "!@#$%^&*()-_=+[]{}|;:,.<>?" + + # Ensure we have at least one of each required character type + password = [ + random.choice(uppercase_letters), + random.choice(lowercase_letters), + random.choice(digits), + random.choice(special_chars) + ] + + # Fill the rest with random characters from all allowed sets + all_chars = uppercase_letters + lowercase_letters + digits + special_chars + for _ in range(length - 4): + password.append(random.choice(all_chars)) + + # Shuffle the password + random.shuffle(password) + + # Convert list to string + return ''.join(password) + +def check_password_complexity(password): + """Checks if a password meets complexity requirements. + + Requirements: + - At least 8 characters long + - Contains at least one uppercase letter + - Contains at least one lowercase letter + - Contains at least one digit + - Contains at least one special character + + :param password (string): The password to check + :return (tuple): (bool, string) - True if the password meets all requirements, + False otherwise, and a message explaining the result + """ + # Check length + if len(password) < 8: + return False, "Password must be at least 8 characters long." + + # Check for uppercase letter + if not any(char.isupper() for char in password): + return False, "Password must contain at least one uppercase letter." + + # Check for lowercase letter + if not any(char.islower() for char in password): + return False, "Password must contain at least one lowercase letter." + + # Check for digit + if not any(char.isdigit() for char in password): + return False, "Password must contain at least one digit." + + # Check for special character + special_chars = "!@#$%^&*()-_+=<>?/[]{}|\\~`" + if not any(char in special_chars for char in password): + return False, "Password must contain at least one special character." + + return True, "Password meets all complexity requirements." + +def add_entry(): + """Adds an entry with an entry title, username, password and url + Includes all user interface interactions to get the necessary information from the user + """ + try: + entry_title = input("Enter entry title: ") + username = input("Enter username: ") + + # Explain password requirements + print("\nPassword requirements:") + print("- At least 8 characters long") + print("- Contains at least one uppercase letter") + print("- Contains at least one lowercase letter") + print("- Contains at least one digit") + print("- Contains at least one special character\n") + + # Ask if user wants to generate a random password + gen_password = input("Would you like to generate a random password? (y/n): ") + + if gen_password.lower() == 'y': + # Ask for desired password length + try: + length = int(input("Enter desired password length (minimum 8, default 12): ") or "12") + if length < 8: + print("Password length must be at least 8. Setting to 8.") + length = 8 + except ValueError: + print("Invalid input. Using default length of 12.") + length = 12 + + # Generate the password + password = generate_random_password(length) + print(f"Generated password: {password}") + is_valid = True + else: + # Get and validate manual password + print("Enter your password manually:") + while True: + password = input("Enter password: ") + is_valid, message = check_password_complexity(password) + if is_valid: + print(message) + break + else: + print(message) + print("Please try again with a stronger password.") + + url = input("Enter URL: ") + + # Encrypt the password + encrypted_password = password_encrypt(password, encryption_key) + + # Add the new entry to the entries dictionary + entries[entry_title] = { + 'username': username, + 'password': encrypted_password, + 'url': url + } + + print(f"Entry '{entry_title}' added successfully!") + except Exception as e: + print(f"Error adding entry: {e}") + +def print_entry(): + """Asks the user for the name of the entry and prints all related information in a pretty format. + Includes all information about an entry. + """ + try: + print("Which entry do you want to lookup the information for?") + for key in entries: + print(key) + + entry = input('Enter entry name: ') + + # Check if the entry exists + if entry in entries: + entry_data = entries[entry] + + # Decrypt the password + decrypted_password = password_decrypt(entry_data['password'], encryption_key) + + # Print the entry information + print("\n--- Entry Information ---") + print(f"Entry: {entry}") + print(f"Username: {entry_data['username']}") + print(f"Password: {decrypted_password}") + print(f"URL: {entry_data['url']}") + print("------------------------\n") + else: + print(f"Entry '{entry}' not found!") + except KeyError: + print(f"Error: The entry does not exist or has incomplete data.") + except Exception as e: + print(f"Error looking up entry: {e}") + +def delete_entry(): + """Deletes an entry from the password manager. + Asks the user for the entry name to delete and removes it if it exists. + + This is additional feature #1. + """ + try: + print("Which entry do you want to delete?") + for key in entries: + print(key) + + entry = input('Enter entry name: ') + + # Check if the entry exists + if entry in entries: + # Ask for confirmation + confirm = input(f"Are you sure you want to delete '{entry}'? (y/n): ") + if confirm.lower() == 'y': + # Remove the entry + del entries[entry] + print(f"Entry '{entry}' deleted successfully!") + else: + print("Deletion cancelled.") + else: + print(f"Entry '{entry}' not found!") + except Exception as e: + print(f"Error deleting entry: {e}") + +def edit_entry(): + """Allows the user to edit an existing entry in the password manager. + The user can update the username, password, and/or URL. + + This is additional feature #2. + """ + try: + print("Which entry do you want to edit?") + for key in entries: + print(key) + + entry = input('Enter entry name: ') + + # Check if the entry exists + if entry in entries: + entry_data = entries[entry] + print(f"\nEditing entry: {entry}") + + # Get current values for reference + current_username = entry_data['username'] + current_url = entry_data['url'] + + # Update username + new_username = input(f"Enter new username (current: {current_username}) or press Enter to keep current: ") + if new_username: + entry_data['username'] = new_username + + # Update password + update_password = input("Do you want to update the password? (y/n): ") + if update_password.lower() == 'y': + # Explain password requirements + print("\nPassword requirements:") + print("- At least 8 characters long") + print("- Contains at least one uppercase letter") + print("- Contains at least one lowercase letter") + print("- Contains at least one digit") + print("- Contains at least one special character (!@#$%^&*()-_+=<>?/[]{}|\\~`)\n") + + # Ask if user wants to generate a random password + gen_password = input("Would you like to generate a random password? (y/n): ") + + if gen_password.lower() == 'y': + # Ask for desired password length + try: + length = int(input("Enter desired password length (minimum 8, default 12): ") or "12") + if length < 8: + print("Password length must be at least 8. Setting to 8.") + length = 8 + except ValueError: + print("Invalid input. Using default length of 12.") + length = 12 + + # Generate the password + new_password = generate_random_password(length) + print(f"Generated password: {new_password}") + + # Encrypt the new password + entry_data['password'] = password_encrypt(new_password, encryption_key) + else: + # Get and validate new password manually + while True: + new_password = input("Enter new password: ") + is_valid, message = check_password_complexity(new_password) + if is_valid: + print(message) + # Encrypt the new password + entry_data['password'] = password_encrypt(new_password, encryption_key) + break + else: + print(message) + print("Please try again with a stronger password.") + + # Update URL + new_url = input(f"Enter new URL (current: {current_url}) or press Enter to keep current: ") + if new_url: + entry_data['url'] = new_url + + print(f"Entry '{entry}' updated successfully!") + else: + print(f"Entry '{entry}' not found!") + except Exception as e: + print(f"Error editing entry: {e}") + +def end_program(): + """Exits the program. + """ + sys.exit() + +def print_dictionary(): + """Prints the current entries dictionary. + For testing purposes only. + """ + print(entries) + +# Menu dictionary mapping user choices to functions +menu_dict = {'1': load_password_file, + '2': add_entry, + '3': print_entry, + '4': save_password_file, + '5': end_program, + '6': print_dictionary, + '7': delete_entry, + '8': edit_entry} + +# Main program loop +while True: + try: + user_choice = input(menu_text) + if user_choice in menu_dict and menu_dict[user_choice]: + menu_dict[user_choice]() + else: + print('Not a valid choice') + except Exception as e: + print(f"An error occurred: {e}") \ No newline at end of file diff --git a/python-csi160/week01/firstprogram.py b/python-csi160/week01/firstprogram.py new file mode 100644 index 0000000..038bae7 --- /dev/null +++ b/python-csi160/week01/firstprogram.py @@ -0,0 +1,14 @@ + +# this program says hello and asks for name, age + + +print('Hello world!') +print('What is your name?') +myName = input() +print('It is good to meet you, ' + myName) +print('The length of your name is:') +print(len(myName)) +print('What is your age?') +myAge = input() +print('You will be ' + str(int(myAge) + 1) + ' in a year.') + diff --git a/python-csi160/week01/pycharm_install.md b/python-csi160/week01/pycharm_install.md new file mode 100644 index 0000000..6c11012 --- /dev/null +++ b/python-csi160/week01/pycharm_install.md @@ -0,0 +1,6 @@ +Install from here: +https://www.jetbrains.com/pycharm/download + +Get license from here: +https://www.jetbrains.com/community/education + diff --git a/python-csi160/week02/Week-2Practice-Problems/part1.py b/python-csi160/week02/Week-2Practice-Problems/part1.py new file mode 100644 index 0000000..ef331f7 --- /dev/null +++ b/python-csi160/week02/Week-2Practice-Problems/part1.py @@ -0,0 +1,10 @@ +# This program reads two numbers and prints their sum: +a = int(input('Enter first number: ')) +b = int(input('Enter second number: ')) +c = int(input('Enter third number: ')) + +print(a + b + c) + +# Can you change it so it can read and sum three numbers? + + diff --git a/python-csi160/week02/Week-2Practice-Problems/part2.py b/python-csi160/week02/Week-2Practice-Problems/part2.py new file mode 100644 index 0000000..2255fbc --- /dev/null +++ b/python-csi160/week02/Week-2Practice-Problems/part2.py @@ -0,0 +1,5 @@ +# Get the user's name +name = input('Enter your name:\n') + +# Print hello statement +print("Hello, " + name + "!") \ No newline at end of file diff --git a/python-csi160/week02/Week-2Practice-Problems/part3.py b/python-csi160/week02/Week-2Practice-Problems/part3.py new file mode 100644 index 0000000..7dda1da --- /dev/null +++ b/python-csi160/week02/Week-2Practice-Problems/part3.py @@ -0,0 +1,7 @@ +# Read an integer: +number = int(input('Enter a number:\n')) + +# Print output for next and previous that matches the instructions + +print("The next number for the number " + str(number) + " is " + str(number + 1)) +print("The previous number for the number " + str(number) + " is " + str(number - 1)) diff --git a/python-csi160/week02/Week-2Practice-Problems/part4.py b/python-csi160/week02/Week-2Practice-Problems/part4.py new file mode 100644 index 0000000..f37a387 --- /dev/null +++ b/python-csi160/week02/Week-2Practice-Problems/part4.py @@ -0,0 +1,7 @@ +# Read the numbers b and h like this: +base = float(input('Enter Base: ')) +height = float(input('Enter Height: ')) + +# Print the result with print() +area = 0.5 * (base * height) +print(area) \ No newline at end of file diff --git a/python-csi160/week02/Week-2Practice-Problems/part5.py b/python-csi160/week02/Week-2Practice-Problems/part5.py new file mode 100644 index 0000000..ca731e1 --- /dev/null +++ b/python-csi160/week02/Week-2Practice-Problems/part5.py @@ -0,0 +1,7 @@ +# Read the numbers like this: +num_students = int(input("Number of students: ")) +num_apples = int(input("Number of apples: ")) + +# Print the result with print() +print(num_apples // num_students) +print(num_apples % num_students) diff --git a/python-csi160/week02/Week-2Practice-Problems/part6.py b/python-csi160/week02/Week-2Practice-Problems/part6.py new file mode 100644 index 0000000..912bb5a --- /dev/null +++ b/python-csi160/week02/Week-2Practice-Problems/part6.py @@ -0,0 +1,9 @@ +# Read an integer: +seconds_past_midnight = int(input()) + + +full_hours_past_midnight = (seconds_past_midnight // 3600) % 24 +full_minutes_past_midnight = (seconds_past_midnight // 60) % 1440 + +print (full_hours_past_midnight, full_minutes_past_midnight) + diff --git a/python-csi160/week02/Week-2Practice-Problems/part7.py b/python-csi160/week02/Week-2Practice-Problems/part7.py new file mode 100644 index 0000000..86a105c --- /dev/null +++ b/python-csi160/week02/Week-2Practice-Problems/part7.py @@ -0,0 +1,11 @@ +# Input the data +cupcake_dollars = int(input()) +cupcake_cents = int(input()) +num_cupcakes = int(input()) + +# Your code here + +total_cost_cents = (((cupcake_dollars * 100) + cupcake_cents) * num_cupcakes) +total_cost_dollars = total_cost_cents // 100 +total_cost_cents = total_cost_cents % 100 +print(total_cost_dollars, total_cost_cents) \ No newline at end of file diff --git a/python-csi160/week02/croce_week02_lab.py b/python-csi160/week02/croce_week02_lab.py new file mode 100644 index 0000000..bce98f9 --- /dev/null +++ b/python-csi160/week02/croce_week02_lab.py @@ -0,0 +1,61 @@ +""" +Author: Charlotte Croce +Class: CSI160 +Assignment: Week 2: Lab - Conversation with a Computer +Due Date: 1/27/25 + +Certification of Authenticity: +I certify that this is entirely my own work, except where I have given +fully-documented references to the work of others. I understand the definition +and consequences of plagiarism and acknowledge that the assessor of this +assignment may, for the purpose of assessing this assignment: +- Reproduce this assignment and provide a copy to another member of academic +- staff; and/or Communicate a copy of this assignment to a plagiarism checking +- service (which may then retain a copy of this assignment on its database for +- the purpose of future plagiarism checking) +""" + + +""" +Write a program that has a conversation with the user. The program must ask for strings, integers and floats as input. +The program must ask for at least 4 different inputs from the user. The program must reuse atleast 4 of these inputs in what it displays on the screen. +The program must perform at least 2 arithmetic operations on the numbers the user inputs. Please turn in your .py file. +""" + +print("hello! i am a robot. beep beep") +# ask for name +name = input("what is your name?") +# say hi and ask for favorite color +favorite_color = input("hello " + name + ", what is your favorite color?") +# ask if user likes ice cream +user_likes_icecream = input("mine too, do you like Ice Cream?") +# answer differently based on whether user answers 'yes' or not +if(user_likes_icecream.lower() == "yes"): + print("me too!") +else: + print("okay, not for everyone") +# ask for age +age = int(input(name + ", how old are you?")) +# ask for number of siblings +siblings = int(input("...and how many siblings do you have?")) +# display how many kids you a part of; ask if favorite color is shared by anyone in the house +is_favorite_color_of_house = input("that means you are one of " + str(siblings + 1) + " kid(s). is " + favorite_color + " the favorite color of anyone else in your house?") +# answer differently based on whether user answers 'yes' or not +if(is_favorite_color_of_house.lower() == "yes"): + print("good you can agree") +else: + print("too bad") +# ask for parent's age +parent_age = int(input('how old is one of your parents?')) +# respond with age of parents when they had the user +print("that means they were likely " + str(parent_age - age) + " when they had you") +# ask for GPA +gpa = float(input("what is your GPA[4-point scale]?")) +# answer differently based on the GPA value entered +if(gpa >= 3.5): + print("great job!") +elif(gpa >= 2.5): + print("keep it up!") +else: + print("time to study more!") +print("goodbye!") diff --git a/python-csi160/week03/Week-3Practice-Problems/part1.py b/python-csi160/week03/Week-3Practice-Problems/part1.py new file mode 100644 index 0000000..3ea01f5 --- /dev/null +++ b/python-csi160/week03/Week-3Practice-Problems/part1.py @@ -0,0 +1,5 @@ +number = int(input('Enter a two digit number: ')) + +# Print the two digits of the number seperated by a space + +print((number // 10),(number % 10)) \ No newline at end of file diff --git a/python-csi160/week03/Week-3Practice-Problems/part2.py b/python-csi160/week03/Week-3Practice-Problems/part2.py new file mode 100644 index 0000000..ca8cb30 --- /dev/null +++ b/python-csi160/week03/Week-3Practice-Problems/part2.py @@ -0,0 +1,7 @@ +# Read an integer: +number = int(input('Enter a two digit number: ')) + +# Print the digits reversed + + +print(str(number % 10) + str(number // 10)) \ No newline at end of file diff --git a/python-csi160/week03/Week-3Practice-Problems/part3.py b/python-csi160/week03/Week-3Practice-Problems/part3.py new file mode 100644 index 0000000..96ff063 --- /dev/null +++ b/python-csi160/week03/Week-3Practice-Problems/part3.py @@ -0,0 +1,7 @@ +# Read an integer: +number = int(input('Enter a 3 digit number: ')) + +# Print the sum of the digits: + +a = ((number // 100) + (number % 100 // 10) + (number % 10)) +print(a) diff --git a/python-csi160/week03/Week-3Practice-Problems/part4.py b/python-csi160/week03/Week-3Practice-Problems/part4.py new file mode 100644 index 0000000..1cbd7fe --- /dev/null +++ b/python-csi160/week03/Week-3Practice-Problems/part4.py @@ -0,0 +1,46 @@ +def days_to_hours(days): + """ Converts days to hours + + Arguments: + days (int): number of days as an integer + + Return: + number of hours (int) + + Assumptions: + days must be an int + """ + return days * 24 + +print('Days to hours:', days_to_hours(3)) +hours = days_to_hours(2) + + +def days_to_minutes(days): + """ Converts days to minutes + + Arguments: + days (int): number of days as an integer + + Return: + number of minutes (int) + + Assumptions: + days must be an int + """ + return days_to_hours(days) * 60 + + +def days_to_seconds(days): + """ Converts days to seconds + + Arguments: + days (int): number of days as an integer + + Return: + number of seconds (int) + + Assumptions: + days must be an int + """ + return days_to_minutes(days) * 60 diff --git a/python-csi160/week03/Week-3Practice-Problems/part5.py b/python-csi160/week03/Week-3Practice-Problems/part5.py new file mode 100644 index 0000000..40ca258 --- /dev/null +++ b/python-csi160/week03/Week-3Practice-Problems/part5.py @@ -0,0 +1,14 @@ +def celsius_to_fahrenheit(temperature_in_celcius): + """This function converts a number from Celcius to Fahrenheit + + Arguments: + temperature_in_celcius (float): The remperature to convert + + Returns: + float: The temperature in Fahrenheit + + Assumptions: + Assumes that temperature_in_celcius is a float + + """ + return (temperature_in_celcius * 1.8) + 32 \ No newline at end of file diff --git a/python-csi160/week03/Week-3Practice-Problems/part6.py b/python-csi160/week03/Week-3Practice-Problems/part6.py new file mode 100644 index 0000000..b3a0907 --- /dev/null +++ b/python-csi160/week03/Week-3Practice-Problems/part6.py @@ -0,0 +1,13 @@ +from math import pi # This lets you refer to pi in your code + + +def volume_cone(radius, height): + """Computes volume of a cone + + :param radius: positive float + + :param height: positive float + + :return: volume of given cone + """ + return 1/3 * pi * (radius*radius) * height \ No newline at end of file diff --git a/python-csi160/week03/croce_week03_lab.py b/python-csi160/week03/croce_week03_lab.py new file mode 100644 index 0000000..63d7f7e --- /dev/null +++ b/python-csi160/week03/croce_week03_lab.py @@ -0,0 +1,87 @@ +""" + +Author: Charlotte Croce +Class: CSI 160 +Assignment: Week 3 Lab +Due Date: 2/3/25 + +Certification of Authenticity: +I certify that this is entirely my own work, except where I have given +fully-documented references to the work of others. I understand the definition +and consequences of plagiarism and acknowledge that the assessor of this +assignment may, for the purpose of assessing this assignment: +- Reproduce this assignment and provide a copy to another member of academic +- staff; and/or Communicate a copy of this assignment to a plagiarism checking +- service (which may then retain a copy of this assignment on its database for +- the purpose of future plagiarism checking) +""" + +from math import pi + + +def fahrenheit_to_celcius(temperature_in_fahrenheit): + """This function converts a number from Fahrenheit to Celcius + + :param temperature_in_fahrenheit (float): The temperature to convert + + :return (float): The temperature in Fahrenheit + + Assumptions: temperature_in_fahrenheit is a float + + """ + try: + return round(((temperature_in_fahrenheit - 32) * 5 / 9), 2) + except TypeError: + print("invalid input: input floats please") + return + +celcius_temp = float(input("---\n1. temp in fahrenheit: ")) +print("1. coverted to celcius:", fahrenheit_to_celcius(celcius_temp)) + + +def cylinder_volume(radius, height): + """Computes volume of a cylinder + + :param radius: positive float + + :param height: positive float + + :return: volume of cylinder + + Assumptions: inputs are floats + """ + try: + return round((pi * (radius*radius) * height), 2) + except TypeError: + print("invalid input: input floats please") + return + +cylinder_radius = float(input("---\n2. cylinder radius: ")) +cylinder_height = float(input("2. cylinder height: ")) +print("2. cylinder volume:", cylinder_volume(cylinder_radius, cylinder_height)) + + +def surface_area_rectangular_prism(length, width, height): + """Computes surface area of a rectangular prism + + :param length: positive float + + :param width: positive float + + :param height: positive float + + :return: surface area of a rectangular prism + + Assumptions: inputs are floats + """ + try: + return round((2 * ((length*width)+(length*height)+(width*height))), 2) + except TypeError: + print("invalid input: input floats please") + return + +rectangular_prism_length = float(input("---\n3. rectangular prism length: ")) +rectangular_prism_width = float(input("3. rectangular prism width: ")) +rectangular_prism_height = float(input("3. rectangular prism height: ")) +print("3. rectangular prism surface area:", surface_area_rectangular_prism(rectangular_prism_length,rectangular_prism_width,rectangular_prism_height)) + diff --git a/python-csi160/week04/Week-4Practice-Problems/part1.py b/python-csi160/week04/Week-4Practice-Problems/part1.py new file mode 100644 index 0000000..ca77acf --- /dev/null +++ b/python-csi160/week04/Week-4Practice-Problems/part1.py @@ -0,0 +1,8 @@ +number = int(input('Enter an integer: ')) + +# Determine odd or even + +if number % 2 == 0: + print("even") +else: + print("odd") diff --git a/python-csi160/week04/Week-4Practice-Problems/part10.py b/python-csi160/week04/Week-4Practice-Problems/part10.py new file mode 100644 index 0000000..fc4f520 --- /dev/null +++ b/python-csi160/week04/Week-4Practice-Problems/part10.py @@ -0,0 +1,26 @@ +def is_legal_bishop_move(initial_x, initial_y, final_x, final_y): + """Returns True / False whether a given move is a legal move for the Bishop. + + This function assumes that there are no other pieces on the board. + + :param initial_x: (int) Horizontal 1-8 + :param initial_y: (int) Vertical 1-8 + :param final_x: (int) Horizontal 1-8 + :param final_y: (int) Vertical 1-8 + :return: (bool) True / False if it is a legal move + """ + # Complete this function + if initial_x == final_x and initial_y == final_y: + return False + return abs(initial_x - final_x) == abs(initial_y - final_y) + + +# Leave this part for easily testing your function +print('(4, 4, 3, 5) It is', is_legal_bishop_move(4, 4, 3, 5), 'that this is a legal move') +print('(1, 4, 4, 7) It is', is_legal_bishop_move(1, 4, 4, 7), 'that this is a legal move') +print('(5, 4, 2, 1) It is', is_legal_bishop_move(5, 4, 2, 1), 'that this is a legal move') +print('(5, 4, 1, 1) It is', is_legal_bishop_move(5, 4, 1, 1), 'that this is a legal move') +print('(5, 4, 6, 4) It is', is_legal_bishop_move(5, 4, 6, 4), 'that this is a legal move') +print('(1, 1, 1, 1) It is', is_legal_bishop_move(1, 1, 1, 1), 'that this is a legal move') + + diff --git a/python-csi160/week04/Week-4Practice-Problems/part2.py b/python-csi160/week04/Week-4Practice-Problems/part2.py new file mode 100644 index 0000000..8e442a7 --- /dev/null +++ b/python-csi160/week04/Week-4Practice-Problems/part2.py @@ -0,0 +1,12 @@ + +number1 = int(input('Enter an integer: ')) +number2 = int(input('Enter an integer: ')) + + +# Print the smaller number + + +if number1 < number2: + print(number1) +else: + print(number2) \ No newline at end of file diff --git a/python-csi160/week04/Week-4Practice-Problems/part3.py b/python-csi160/week04/Week-4Practice-Problems/part3.py new file mode 100644 index 0000000..b19f0f8 --- /dev/null +++ b/python-csi160/week04/Week-4Practice-Problems/part3.py @@ -0,0 +1,9 @@ +num = int(input('Enter a number: ')) + +# Print out result +if num > 0: + print("1") +elif num < 0: + print("-1") +else: + print("0") \ No newline at end of file diff --git a/python-csi160/week04/Week-4Practice-Problems/part4.py b/python-csi160/week04/Week-4Practice-Problems/part4.py new file mode 100644 index 0000000..c76ec95 --- /dev/null +++ b/python-csi160/week04/Week-4Practice-Problems/part4.py @@ -0,0 +1,7 @@ +year = int(input('Enter the year: ')) + +# Prints Yes or No based on if year is in the 21st century +if year >= 2001 and year <= 2100: + print("YES") +else: + print("NO") \ No newline at end of file diff --git a/python-csi160/week04/Week-4Practice-Problems/part5.py b/python-csi160/week04/Week-4Practice-Problems/part5.py new file mode 100644 index 0000000..14effb4 --- /dev/null +++ b/python-csi160/week04/Week-4Practice-Problems/part5.py @@ -0,0 +1,16 @@ +def one_positive(num1, num2): + """Given two non-zero integers, returns True if exactly one of + them is positive and returns False otherwise. + + :param num1: non-zero integer + :param num2: non-zero integer + :return: True / False + """ + # Complete this function + return (num1 > 0) ^ (num2 > 0) + + +# Leave this part for easily testing your function +print('(5, 7) It is', one_positive(5, 7), 'that only one of these numbers is positive') +print('(-5, -7) It is', one_positive(-5, -7), 'that only one of these numbers is positive') +print('(5, -7) It is', one_positive(5, -7), 'that only one of these numbers is positive') \ No newline at end of file diff --git a/python-csi160/week04/Week-4Practice-Problems/part6.py b/python-csi160/week04/Week-4Practice-Problems/part6.py new file mode 100644 index 0000000..d31e73e --- /dev/null +++ b/python-csi160/week04/Week-4Practice-Problems/part6.py @@ -0,0 +1,27 @@ +def ascending_digits(num): + """Given a three-digit integer X consisting of three different digits, + returns True if its three digits are going in an ascending + order from left to right and returns False otherwise. + + :param num: three digit integer + :return: True / False + """ + # Complete this function + # Hint: assign variables for each digit first + # then build the comparison + + a = num // 100 + b = num % 100 // 10 + c = num % 10 + + ascending=False + if a < b and b < c: + ascending = True + + return ascending + + +# Leave this part for easily testing your function +print('(136) It is', ascending_digits(136), 'that the digits are ascending') +print('(462) It is', ascending_digits(462), 'that the digits are ascending') +print('(823) It is', ascending_digits(823), 'that the digits are ascending') \ No newline at end of file diff --git a/python-csi160/week04/Week-4Practice-Problems/part7.py b/python-csi160/week04/Week-4Practice-Problems/part7.py new file mode 100644 index 0000000..044830b --- /dev/null +++ b/python-csi160/week04/Week-4Practice-Problems/part7.py @@ -0,0 +1,20 @@ +month = int(input('Enter the month: ')) + + +if month == 1 or month == 3 or month == 5 or month == 7 or month == 8 or month == 10 or month == 12: + print("31") +elif month == 4 or month == 6 or month == 9 or month == 11: + print("30") +else: + print("28") + +''' +month = month.lower() + +if month == "january" or month == "march" or month == "may" or month == "july" or month == "august" or month == "october" or month == "december": + print("31") +elif month == "april" or month == "june" or month == "september" or month == "november": + print("30") +else: + print("28") +''' \ No newline at end of file diff --git a/python-csi160/week04/Week-4Practice-Problems/part8.py b/python-csi160/week04/Week-4Practice-Problems/part8.py new file mode 100644 index 0000000..0659f2d --- /dev/null +++ b/python-csi160/week04/Week-4Practice-Problems/part8.py @@ -0,0 +1,18 @@ +def is_legal_rook_move(initial_x, initial_y, final_x, final_y): + """Returns True / False whether a given move is a legal move for the Rook. + + This function assumes that there are no other pieces on the board. + + :param initial_x: (int) Horizontal 1-8 + :param initial_y: (int) Vertical 1-8 + :param final_x: (int) Horizontal 1-8 + :param final_y: (int) Vertical 1-8 + :return: (bool) True / False if it is a legal move + """ + # Complete this function + return (initial_x != final_x) ^ (initial_y != final_y) + +# Leave this part for easily testing your function +print('(4, 4, 5, 5) It is', is_legal_rook_move(4, 4, 5, 5), 'that this is a legal move') +print('(1, 4, 6, 4) It is', is_legal_rook_move(1, 4, 6, 4), 'that this is a legal move') +print('(1, 4, 1, 7) It is', is_legal_rook_move(1, 4, 1, 7), 'that this is a legal move') diff --git a/python-csi160/week04/Week-4Practice-Problems/part9.py b/python-csi160/week04/Week-4Practice-Problems/part9.py new file mode 100644 index 0000000..2ad5090 --- /dev/null +++ b/python-csi160/week04/Week-4Practice-Problems/part9.py @@ -0,0 +1,24 @@ +def is_legal_king_move(initial_x, initial_y, final_x, final_y): + """Returns True / False whether a given move is a legal move for the King. + + This function assumes that there are no other pieces on the board. + + :param initial_x: (int) Horizontal 1-8 + :param initial_y: (int) Vertical 1-8 + :param final_x: (int) Horizontal 1-8 + :param final_y: (int) Vertical 1-8 + :return: (bool) True / False if it is a legal move + """ + # Complete this function + + if initial_x == final_x and initial_y == final_y: + return False + return abs(initial_x - final_x) <= 1 and abs(initial_y - final_y) <= 1 + + + + +# Leave this part for easily testing your function +print('(4, 4, 5, 5) It is', is_legal_king_move(4, 4, 5, 5), 'that this is a legal move') +print('(1, 4, 6, 4) It is', is_legal_king_move(1, 4, 6, 4), 'that this is a legal move') +print('(1, 4, 1, 3) It is', is_legal_king_move(1, 4, 1, 3), 'that this is a legal move') diff --git a/python-csi160/week04/week04_labs/croce_week04_lab_01.py b/python-csi160/week04/week04_labs/croce_week04_lab_01.py new file mode 100644 index 0000000..2a6afe5 --- /dev/null +++ b/python-csi160/week04/week04_labs/croce_week04_lab_01.py @@ -0,0 +1,14 @@ + +#1. Implement a voting test. The user enters their age and then the program prints either, +# “You must be 18 to vote” or “You are of voting age”. + +def voting_test(): + age = int(input("age: ")) + if age >= 18: + print("You are of voting age") + else: + print("You must be 18 to vote") + + +voting_test() + diff --git a/python-csi160/week04/week04_labs/croce_week04_lab_02.py b/python-csi160/week04/week04_labs/croce_week04_lab_02.py new file mode 100644 index 0000000..74da7d7 --- /dev/null +++ b/python-csi160/week04/week04_labs/croce_week04_lab_02.py @@ -0,0 +1,25 @@ + +#2. Ask the user to enter a grade percentage. Convert the grade into a letter +# grade using the official Champlain College grading scale. For instance, if the user +# types 99 then print A+. + +def grade_to_letter(): + grade = int(input("GPA (100pt scale): ")) + if grade >= 97: letter = "A+" + elif grade >= 93: letter = "A" + elif grade >= 90: letter = "A-" + elif grade >= 87: letter = "B+" + elif grade >= 83: letter = "B" + elif grade >= 80: letter = "B-" + elif grade >= 77: letter = "C+" + elif grade >= 73: letter = "C" + elif grade >= 70: letter = "C-" + elif grade >= 67: letter = "C+" + elif grade >= 63: letter = "C" + elif grade >= 60: letter = "C-" + else: letter = "F" + print(letter) + + +grade_to_letter() + diff --git a/python-csi160/week04/week04_labs/croce_week04_lab_03.py b/python-csi160/week04/week04_labs/croce_week04_lab_03.py new file mode 100644 index 0000000..94bd96a --- /dev/null +++ b/python-csi160/week04/week04_labs/croce_week04_lab_03.py @@ -0,0 +1,16 @@ + +# 3. Write a program that asks for two numbers. If the sum of the numbers is greater than +# 100, print "They add up to a big number" if it is less than/equal to 100 than print "They add up to ____". + +def add_to_big_number(): + num1 = int(input("num1: ")) + num2 = int(input("num2: ")) + sum = num1 + num2 + if sum > 100: + print("They add up to a big number") + else: + print("They add up to " + str(sum)) + + +add_to_big_number() + diff --git a/python-csi160/week04/week04_labs/croce_week04_lab_04.py b/python-csi160/week04/week04_labs/croce_week04_lab_04.py new file mode 100644 index 0000000..6fa6070 --- /dev/null +++ b/python-csi160/week04/week04_labs/croce_week04_lab_04.py @@ -0,0 +1,17 @@ + +#4. Implement a random number guessing game. The computer will pick a number at random from +# 0-9, the user will be asked to guess the number. Inform the user if they get the answer correct. + +from random import randint + +def random_number_game(): + num = randint(0,9) + guess = int(input("random number guess(0-9): ")) + if guess == num: + print("correct! you win") + else: + print("incorrect, the anser was", num) + + +random_number_game() + diff --git a/python-csi160/week04/week04_labs/croce_week04_lab_05.py b/python-csi160/week04/week04_labs/croce_week04_lab_05.py new file mode 100644 index 0000000..d03bbc4 --- /dev/null +++ b/python-csi160/week04/week04_labs/croce_week04_lab_05.py @@ -0,0 +1,13 @@ + +# 5. Write a function to compute whether a given year is a leap year in the Hebrew calendar. + +def is_hebrew_leap_year(year): + year_of_cycle = year % 19 + if year_of_cycle in (3, 6, 8, 11, 14, 17, 19): + print(str(year) + " is year number " + str(year_of_cycle) + " of the cycle and is therefore a leap year.") + else: + print(str(year) + " is year number " + str(year_of_cycle) + " of the cycle and is therefore NOT a leap year.") + + +is_hebrew_leap_year(5779) +is_hebrew_leap_year(5780) diff --git a/python-csi160/week04/week04_labs/croce_week04_labs_ALL.py b/python-csi160/week04/week04_labs/croce_week04_labs_ALL.py new file mode 100644 index 0000000..0a6b841 --- /dev/null +++ b/python-csi160/week04/week04_labs/croce_week04_labs_ALL.py @@ -0,0 +1,85 @@ + +#1. Implement a voting test. The user enters their age and then the program prints either, +# “You must be 18 to vote” or “You are of voting age”. + +def voting_test(): + age = int(input("age: ")) + if age >= 18: + print("You are of voting age") + else: + print("You must be 18 to vote") + + +voting_test() + + +#2. Ask the user to enter a grade percentage. Convert the grade into a letter +# grade using the official Champlain College grading scale. For instance, if the user +# types 99 then print A+. + +def grade_to_letter(): + grade = int(input("GPA (100pt scale): ")) + if grade >= 97: letter = "A+" + elif grade >= 93: letter = "A" + elif grade >= 90: letter = "A-" + elif grade >= 87: letter = "B+" + elif grade >= 83: letter = "B" + elif grade >= 80: letter = "B-" + elif grade >= 77: letter = "C+" + elif grade >= 73: letter = "C" + elif grade >= 70: letter = "C-" + elif grade >= 67: letter = "C+" + elif grade >= 63: letter = "C" + elif grade >= 60: letter = "C-" + else: letter = "F" + print(letter) + + +grade_to_letter() + + +# 3. Write a program that asks for two numbers. If the sum of the numbers is greater than +# 100, print "They add up to a big number" if it is less than/equal to 100 than print "They add up to ____". + +def add_to_big_number(): + num1 = int(input("num1: ")) + num2 = int(input("num2: ")) + sum = num1 + num2 + if sum > 100: + print("They add up to a big number") + else: + print("They add up to " + str(sum)) + + +add_to_big_number() + + +#4. Implement a random number guessing game. The computer will pick a number at random from +# 0-9, the user will be asked to guess the number. Inform the user if they get the answer correct. + +from random import randint + +def random_number_game(): + num = randint(0,9) + guess = int(input("random number guess(0-9): ")) + if guess == num: + print("correct! you win") + else: + print("incorrect, the anser was", num) + + +random_number_game() + + +# 5. Write a function to compute whether a given year is a leap year in the Hebrew calendar. + +def is_hebrew_leap_year(year): + year_of_cycle = year % 19 + if year_of_cycle in (3, 6, 8, 11, 14, 17, 19): + print(str(year) + " is year number " + str(year_of_cycle) + " of the cycle and is therefore a leap year.") + else: + print(str(year) + " is year number " + str(year_of_cycle) + " of the cycle and is therefore NOT a leap year.") + + +is_hebrew_leap_year(5779) +is_hebrew_leap_year(5780) diff --git a/python-csi160/week05/croce_week5_lab.py b/python-csi160/week05/croce_week5_lab.py new file mode 100644 index 0000000..81b6b83 --- /dev/null +++ b/python-csi160/week05/croce_week5_lab.py @@ -0,0 +1,104 @@ +# Charlotte Croce +# CSI 160: week5 lab +# 2/13/2025 + +import math + +def number_of_zeros(grades): + """Given a list of grades, determines the number of grades that are 0% + + params: + grades (list of floats) - The grades to search. Example [75, 82.5, 97, 0, 87.5] + + return (int) - the number of 0% grades + """ + count = 0 + for grade in grades: + if grade == 0: + count += 1 + return count + + +def median(numbers): + """Find the median of the given list of numbers. + + How to find the median: + https://www.mathsisfun.com/median.html + + Note: Write your own implementation and do not use any libraries. You will need to sort the list. + + params: + numbers (list) A list containing either int or float elements + + return (numeric) The median value as either an int or float + """ + numbers.sort() + length = len(numbers) + middle = length // 2 + if length % 2 == 0: # even number-> avg of middle two + return (numbers[middle - 1] + numbers[middle]) / 2 + else: # odd number-> middle element + return numbers[middle] + + +def top_quartile(grades): + """Return the top 25% of the grades in the supplied list of grades. Round up when determining how many grades to include in the top 25%. + + Hint: You will need to sort the list of grades + + params: + grades (list of floats) Example [75, 82.5, 97, 0, 87.5] + + return (list of floats) - The top 25% + """ + grades.sort() + quarter = math.ceil(len(grades) / 4) + return grades[-quarter:] + + +def domain_name_extractor(url): + """Given a url, return the domain name + + You will need to utilize the .find method to complete this https://docs.python.org/3/library/stdtypes.html#str.find + + Hint: Find the starting point of the domain name, then find the end point. + params: + url (string) the url to search. Example: https://docs.python.org/3/library + + return (string) The domain name or IP address. Example: docs.python.org + """ + start_index = url.find('//') + 2 # find the start of the domain name after http(s):// + end_index = url.find('/', start_index) # starting search from start_index + if end_index == -1: # no '/' found after domain name, or it's the last character + return url[start_index:] + return url[start_index:end_index] + +def test_number_of_zeros(): + print('Running number_of_zeros tests:') + print('Test 1 passed -', number_of_zeros([75.0, 0.0, 97.0, 0.0, 87.5]) == 2) + print('Test 2 passed -', number_of_zeros([]) == 0) + +def test_median(): + print('Running median tests:') + print('Test 1 passed -', median([10, 5, 8, 4, -1]) == 5) + print('Test 2 passed -', median([10, 8, 4, -1]) == 6) + +def test_top_quartile(): + print('Running top_quartile tests:') + print('Test 1 passed -', top_quartile([97, 92.5, 84, 79, 67]) == [92.5, 97]) + print('Test 2 passed -', top_quartile([92.5, 86, 89, 75]) == [92.5]) + +def test_domain_name_extractor(): + print('Running domain_name_extractor tests:') + print('Test 1 passed -', domain_name_extractor('https://champlain.instructure.com/courses/8933') == 'champlain.instructure.com') + print('Test 2 passed -', domain_name_extractor('ftp://champlain.edu/myfile.pdf') == 'champlain.edu') + +print('Running Unit Tests\n') +test_number_of_zeros() +print() +test_median() +print() +test_top_quartile() +print() +test_domain_name_extractor() + diff --git a/python-csi160/week05/week-5Practice-Problems/part1.py b/python-csi160/week05/week-5Practice-Problems/part1.py new file mode 100644 index 0000000..025d506 --- /dev/null +++ b/python-csi160/week05/week-5Practice-Problems/part1.py @@ -0,0 +1,10 @@ +def first_element(list_to_search): + """Returns the first element of the supplied list. Returns None if the list was empty""" + if len(list_to_search) == 0: + return None + return list_to_search[0] + + +# Leave this part for easily testing your function +print('[4, 2, 15, 5] The first_element returns', first_element([4, 2, 15, 5])) +print('[] The first_element returns', first_element([])) diff --git a/python-csi160/week05/week-5Practice-Problems/part2.py b/python-csi160/week05/week-5Practice-Problems/part2.py new file mode 100644 index 0000000..0804dd0 --- /dev/null +++ b/python-csi160/week05/week-5Practice-Problems/part2.py @@ -0,0 +1,10 @@ +def second_element(list_to_search): + """Returns the second element of the supplied list. Returns None if list contains less than 2 elements""" + if len(list_to_search) < 2: + return None + return list_to_search[1] + + +# Leave this part for easily testing your function +print('[4, 2, 15, 5] The second_element returns', second_element([4, 2, 15, 5])) +print('[3] The second_element returns', second_element([3])) diff --git a/python-csi160/week05/week-5Practice-Problems/part3.py b/python-csi160/week05/week-5Practice-Problems/part3.py new file mode 100644 index 0000000..4d020d8 --- /dev/null +++ b/python-csi160/week05/week-5Practice-Problems/part3.py @@ -0,0 +1,11 @@ +def last_element(list_to_search): + """Returns the last element of the supplied list. + Returns None if the list is empty""" + if len(list_to_search) == 0: + return None + return list_to_search[-1] + + +# Leave this part for easily testing your function +print('[4, 2, 15, 5] The last_element returns', last_element([4, 2, 15, 5])) +print('[] The last_element returns', last_element([])) diff --git a/python-csi160/week05/week-5Practice-Problems/part4.py b/python-csi160/week05/week-5Practice-Problems/part4.py new file mode 100644 index 0000000..f757014 --- /dev/null +++ b/python-csi160/week05/week-5Practice-Problems/part4.py @@ -0,0 +1,13 @@ +def area_code(phone_number): + """ Given a phone number in the format: 802-555-1212 + extract the first 3 characters and return this as a string + + :param phone_number: (str) Must be formatted "XXX-XXX-XXXX" + :return: (str) 3 digit area_code + """ + return phone_number[:3] + + +# Leave this part for easily testing your function +print('"802-555-1212" area_code returns', area_code("802-555-1212")) +print('"410-617-3452" area_code returns', area_code("410-617-3452")) diff --git a/python-csi160/week05/week-5Practice-Problems/part5.py b/python-csi160/week05/week-5Practice-Problems/part5.py new file mode 100644 index 0000000..38a4484 --- /dev/null +++ b/python-csi160/week05/week-5Practice-Problems/part5.py @@ -0,0 +1,12 @@ +def last_four_digits(phone_number): + """ Returns the last 4 digits of a phone number as a string + + :param phone_number: (str) May be formatted "XXX-XXX-XXXX" or "1-XXX-XXX-XXXX" + :return: (str) last four digits + """ + return phone_number[-4:] + + +# Leave this part for easily testing your function +print('"802-555-1212" last_four_digits returns', last_four_digits("802-555-1212")) +print('"1-410-617-3452" last_four_digits returns', last_four_digits("410-617-3452")) diff --git a/python-csi160/week05/week-5Practice-Problems/part6.py b/python-csi160/week05/week-5Practice-Problems/part6.py new file mode 100644 index 0000000..88c703e --- /dev/null +++ b/python-csi160/week05/week-5Practice-Problems/part6.py @@ -0,0 +1,13 @@ +def first_last_name(full_name): + """ Returns a tuple with the first and last name. + + :param full_name: (str) Contains a first and last name seperated by a space. + There is only a single space in the full_name. + :return: (tuple) Tuple containing first and last names + """ + return tuple(full_name.split(" ")) + + +# Leave this part for easily testing your function +print('"Billie Holiday" first_last_name returns', first_last_name("Billie Holiday")) +print('"James Brown" first_last_name returns', first_last_name("James Brown")) diff --git a/python-csi160/week05/week-5Practice-Problems/part7.py b/python-csi160/week05/week-5Practice-Problems/part7.py new file mode 100644 index 0000000..713c322 --- /dev/null +++ b/python-csi160/week05/week-5Practice-Problems/part7.py @@ -0,0 +1,15 @@ +def second_smallest(numbers): + """Returns the second smallest number + + :param numbers: (list) List of numbers of at least size 2 + :return: (int or float) The second smallest number + """ + numbers.sort() + return numbers[1] + + +# Leave this part for easily testing your function +print('[6, 3, 9, 2, 1] second_smallest returns', second_smallest([6, 3, 9, 2, 1])) +print('[23, 23.25, 23.5, 23] second_smallest returns', second_smallest([23, 23.25, 23.5, 23])) + + diff --git a/python-csi160/week05/week-5Practice-Problems/part8.py b/python-csi160/week05/week-5Practice-Problems/part8.py new file mode 100644 index 0000000..c6cae48 --- /dev/null +++ b/python-csi160/week05/week-5Practice-Problems/part8.py @@ -0,0 +1,24 @@ +def area_code(phone_number): + """Returns the area code of the supplied phone number. + + params: + phone_number (string) in the format: + 1-XXX-XXX-XXXX + XXX-XXX-XXXX + (XXX)-XXX-XXXX + return: (string) The area code + """ + if phone_number[0] == '(': + return phone_number[1:4] + elif phone_number[0] == '1': + return phone_number[2:5] + else: + return phone_number[:3] + + + + +# Leave this part for easily testing your function +print('"1-617-555-1212" area_code returns', area_code("1-617-555-1212")) +print('"802-999-1212" area_code returns', area_code("802-999-1212")) +print('"(802)-999-1212" area_code returns', area_code("(802)-999-1212")) diff --git a/python-csi160/week06/croce_week6_lab.py b/python-csi160/week06/croce_week6_lab.py new file mode 100644 index 0000000..2b84be8 --- /dev/null +++ b/python-csi160/week06/croce_week6_lab.py @@ -0,0 +1,150 @@ +# Charlotte Croce +# CSI 160 +# Week 6: Lab - Loops +# 2/17/25 + +# 1. Area Codes +# Given a list of phone numbers that are missing the area code, +# append the area code to the phone numbers in the list and return the result list. + +def add_area_code(phone_numbers, area_code): + """Returns a list of phone numbers with the area code added. + Given a list of phone numbers that are missing the area code, + append the area code to the phone numbers in the list and return the result list. + + :param phone_numbers: (list) A list of phone numbers (strings) that do not have the area code + Example: ['555-1212'] + :param area_code: (str) The area code to add Example: '802' + :return: (list) A list of phone numbers with the area code Example: ['802-555-1212'] + """ + phone_numbers_with_area = phone_numbers.copy() + for i in range(len(phone_numbers_with_area)): + phone_numbers_with_area[i] = area_code + '-' + phone_numbers[i] + return phone_numbers_with_area + +# example usage +phone_numbers = ['555-1212', '999-0738'] +with_area_code = add_area_code(phone_numbers, '802') +print(with_area_code) + +################################################################ +# 2. Print even numbers +# Complete the following function to print the even numbers of a list, one per line. + +def print_even(numbers): + """Prints the even numbers in a list, one per line + + :param numbers: (list) list of integers + :return: None + """ + for number in numbers: + if number % 2 == 0: + print(number) + +print_even([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) + + +################################################################ +# 3. Guessing Game +# Extend your guessing game from earlier. Write a program that picks a random number from 1-100. Then ask the user to guess a number. +# Tell the user if the answer is higher or lower than the number they guessed, or if they got the correct answer. +# Allow them to guess again if they got the guess incorrect. They should be able to guess numbers an infinite number +# of times until they get the correct answer, at which point your loop will end. + +# To generate a number from 1-100 you will need the following code at the beginning of your program: + +from random import randint + +def guessing_game(): + """Plays a guessing game where the user guesses a number between 1 and 100 + + :return: None + """ + randomNum = randint(1, 100) + while True: + guess = int(input("Guess a number 1-100: ")) + if guess < randomNum: + print("Higher") + elif guess > randomNum: + print("Lower") + else: + print("Correct!") + break + +guessing_game() + +################################################################ +#4. Backpack of Stuff +#Complete the following code. Fill in the two sections of code identified in the comments. + +import sys + +def backpack_of_stuff(): + """Allows user to add and check items in a backpack + + :return: None + """ + itemsInBackpack = ["book", "computer", "keys", "travel mug"] + + while True: + print("Would you like to:") + print("1. Add an item to the backpack?") + print("2. Check if an item is in the backpack?") + print("3. Quit") + userChoice = input() + + if(userChoice == "1"): + print("What item do you want to add to the backpack?") + itemToAdd = input() + itemsInBackpack.append(itemToAdd) + + if(userChoice == "2"): + print("What item do you want to check to see if it is in the backpack?") + itemToCheck = input() + if itemToCheck in itemsInBackpack: + print("yes, this item is in backpack") + else: + print("no, this item is not in backpack") + + if(userChoice == "3"): + #sys.exit() + break + +backpack_of_stuff() + +################################################################ +# 5. Comma Code +# Say you have a list value like this: + +# listToPrint = ['apples', 'bananas', 'tofu', 'cats'] +#Write a program that prints a list with all the items separated by a comma and a space, +# with and inserted before the last item. For example, the above list would print 'apples, bananas, tofu, and cats'. +# But your program should be able to work with any list not just the one shown above. +# Because of this, you will need to use a loop in case the list to print is shorter or longer than the above list. +# Do not modify the list by inserting 'and' into the list and do not simply print the entire list +# (you must loop through printing each item individually). This problem is trickier than it appears at first glance. + +def comma_code(listToPrint): + """Prints a list with all the items separated by a comma and a space, with 'and' inserted before the last item + + :param listToPrint: (list) A list of strings + :return: None + """ + + # cases for list being 2, 1, or 0 elements + if len(listToPrint) == 0: + print("List is empty") + return + elif len(listToPrint) == 1: + print(listToPrint[0]) + return + elif len(listToPrint) == 2: + print(listToPrint[0] + " and " + listToPrint[1]) + return + + else: + for i in range(len(listToPrint) - 1): # loop through all but last element + print(listToPrint[i], end=", ") + print("and " + listToPrint[-1]) #print final element of list + +comma_code(['apples', 'bananas', 'tofu', 'cats', 'dogs']) \ No newline at end of file diff --git a/python-csi160/week06/week6practiceproblems/part1.py b/python-csi160/week06/week6practiceproblems/part1.py new file mode 100644 index 0000000..29c95f0 --- /dev/null +++ b/python-csi160/week06/week6practiceproblems/part1.py @@ -0,0 +1,7 @@ +#1 initialize the loop +x = int(input('What number do you want to start at? ')) + +# Print countdown using while loop with one number per line +while x > 0: + print(x) + x -= 1 \ No newline at end of file diff --git a/python-csi160/week06/week6practiceproblems/part2.py b/python-csi160/week06/week6practiceproblems/part2.py new file mode 100644 index 0000000..70a7315 --- /dev/null +++ b/python-csi160/week06/week6practiceproblems/part2.py @@ -0,0 +1,8 @@ +a = int(input('What number do you want to start at? ')) +b = int(input('What number do you want to end at? ')) + +# Print all numbers from a to b inclusively. Assume (a ≤ b) + +while a <= b: + print(a) + a += 1 \ No newline at end of file diff --git a/python-csi160/week06/week6practiceproblems/part3.py b/python-csi160/week06/week6practiceproblems/part3.py new file mode 100644 index 0000000..0d32fc7 --- /dev/null +++ b/python-csi160/week06/week6practiceproblems/part3.py @@ -0,0 +1,18 @@ +def all_squares(n): + """Returns a list that contains all the squares of positive integers + where the square is less than or equal to N, in ascending order. + + :param n: (int) Upper bound + :return: (list) List of squares + """ + squares = [] + i = 1 + while i * i <= n: + squares.append(i * i) + i += 1 + return squares + + +# Leave this part for easily testing your function +print('all_squares(50) returns:', all_squares(50)) +print('all_squares(9) returns:', all_squares(9)) diff --git a/python-csi160/week06/week6practiceproblems/part4.py b/python-csi160/week06/week6practiceproblems/part4.py new file mode 100644 index 0000000..d25e474 --- /dev/null +++ b/python-csi160/week06/week6practiceproblems/part4.py @@ -0,0 +1,21 @@ +def introductions(names): + """Prints introductions. + + An introduction is 'Hello' followed by a space and a name. + Include a newline after each introduction. + Example: + 'Hello Josh' + + Important: Your function should use print() and not have a return statement + + :param names: (list) First Names as strings + :return: None + """ + for name in names: + print("Hello", name) + + +# Leave this part for easily testing your function +sample_names = input('Enter the names separated by a comma and a space: ').split(', ') +introductions(sample_names) + diff --git a/python-csi160/week06/week6practiceproblems/part5.py b/python-csi160/week06/week6practiceproblems/part5.py new file mode 100644 index 0000000..1344f62 --- /dev/null +++ b/python-csi160/week06/week6practiceproblems/part5.py @@ -0,0 +1,25 @@ +def num_distinct_elements(numbers): + """Determine the number of distinct elements in the list + + :param numbers: (list) A list of numbers (int or float) + :return: (int) Number of distinct elements + """ + # Use the function sorted() to temporarily sort the numbers + # into ascending order or use the method .sort() to permanently + # sort the list in ascending order. + numbers.sort() + unique_numbers = 1 + for i in range(1, len(numbers)): + if numbers[i] != numbers[i - 1]: + unique_numbers += 1 + return unique_numbers + + + + +# Leave this part for easily testing your function +test1 = [2, 5, 5, 7,2, 9.5, 2, 4] +print(f'num_distinct_elements({test1}) returns:', num_distinct_elements(test1)) +test2 = [2, 1, 1, 7, 1, 9.5, 2, 1] +print(f'num_distinct_elements({test2}) returns:', num_distinct_elements(test2)) + diff --git a/python-csi160/week06/week6practiceproblems/part6.py b/python-csi160/week06/week6practiceproblems/part6.py new file mode 100644 index 0000000..8a30d90 --- /dev/null +++ b/python-csi160/week06/week6practiceproblems/part6.py @@ -0,0 +1,15 @@ +def fibonacci(n): + """Return the nth Fibonacci number. + + param n: (int) position to determine fibonacci of + return: (int) value at position n + """ + + fib_numbers = [0, 1] + for i in range(2, n + 1): + fib_numbers.append(fib_numbers[i - 1] + fib_numbers[i - 2]) + return fib_numbers[n] + +# Leave this part for easily testing your function +print('fibonacci(6) returns:', fibonacci(6), 'expected 8') +print('fibonacci(3) returns:', fibonacci(3), 'expected 2') diff --git a/python-csi160/week07/tictactoe.py b/python-csi160/week07/tictactoe.py new file mode 100644 index 0000000..3d57b93 --- /dev/null +++ b/python-csi160/week07/tictactoe.py @@ -0,0 +1,133 @@ +import os +import time + +# Constants in are named in all caps (PEP8 Standard) +PLAYER_X = 'X' +PLAYER_O = 'O' +EMPTY = ' ' +TIE_GAME = 'tie' +BOARD_SIZE = 3 + +current_player = PLAYER_X # Player X goes first + +# Builds an EMPTY board +board = [[EMPTY,EMPTY,EMPTY], + [EMPTY,EMPTY,EMPTY], + [EMPTY,EMPTY,EMPTY]] + + +def print_board(): + # Clear the screen + os.system('cls' if os.name == 'nt' else 'clear') + + """Prints the board to the console""" + print(' 0 1 2') + print(' -------------') + for i, row in enumerate(board): + print(i, end="") + for square in row: + print(' | ' + square, end="") + print(' |') + print(' -------------') + + + +def is_empty(row, col): + """Returns True/False if a square is EMPTY + + params row, col: (int) The row and Column to Check + return: (boolean) If the row is EMPTY + """ + return board[row][col] == EMPTY + + +def move(player, row, col): + """Makes a game move + + If a move is legal, moves the player to the row and col + and returns True. If a move is illegal, no move is made + and returns False. Hint: Should make use of is_empty() + + param player: Either PLAYER_X or PLAYER_O + param row, col: (int) The row and Column to move to + return: (boolean) Success of the move + """ + if is_empty(row, col): + board[row][col] = player + return True + return False + + + +def determine_winner(): + """Determine if there is a winner + + return: Returns None if there is no winner. + Returns PLAYER_O or PLAYER_X if one of them won. + Returns 'tie' if noone wins + """ + # Step 1: Check the horizontals looking for a winner. + # If so return winner. + for row in board: + if row[0] == row[1] == row[2] != EMPTY: + return row[0] + # Step 2: Check the verticals looking for a winner + # If so return winner. + for col in range(BOARD_SIZE): + if board[0][col] == board[1][col] == board[2][col] != EMPTY: + return board[0][col] + # Step 3: Check the diagonals looking for a winner + # If so return winner. + if board[0][0] == board[1][1] == board[2][2] != EMPTY: + return board[0][0] + if board[0][2] == board[1][1] == board[2][0] != EMPTY: + return board[0][2] + # Step 4: Check to see if there are empty squares. + # If there are empty squares, return None because + # noone has won the game yet + # If there are no empty squares return TIE_GAME + # because we didn't find a winner and all moves are made + for row in board: + for col in row: + if col == EMPTY: + return None + return TIE_GAME + + + +while True: + print() + print_board() + print() + print('It is', current_player, 'turn') + row = int(input('What is the row (0-3)? ')) + col = int(input('What is the col (0-3)? ')) + + # Make sure the move is legal, if so make the move + if is_empty(row, col): + move(current_player, row, col) + else: + print('That is not a legal move!') + time.sleep(2) + continue + + # Check if there is a winner + winner = determine_winner() + if winner in (PLAYER_O, PLAYER_X): + print_board() + print('Congratulations', winner,'!!! You won!') + print('But you are all winners') + break + + if winner == TIE_GAME: + print_board() + print("It's a tie!!!") + break + + # Let the other player have a turn + if current_player == PLAYER_O: + current_player = PLAYER_X + else: + current_player = PLAYER_O + + diff --git a/python-csi160/week10/alice.py b/python-csi160/week10/alice.py new file mode 100644 index 0000000..8075d68 --- /dev/null +++ b/python-csi160/week10/alice.py @@ -0,0 +1,1768 @@ +alice_text = """Down the Rabbit-Hole +Alice was beginning to get very tired of sitting by her sister on the bank, and of having nothing to do: once or twice she had peeped into the book her sister was reading, but it had no pictures or conversations in it, “and what is the use of a book,” thought Alice “without pictures or conversations?” + +So she was considering in her own mind (as well as she could, for the hot day made her feel very sleepy and stupid), whether the pleasure of making a daisy-chain would be worth the trouble of getting up and picking the daisies, when suddenly a White Rabbit with pink eyes ran close by her. + +There was nothing so very remarkable in that; nor did Alice think it so very much out of the way to hear the Rabbit say to itself, “Oh dear! Oh dear! I shall be late!” (when she thought it over afterwards, it occurred to her that she ought to have wondered at this, but at the time it all seemed quite natural); but when the Rabbit actually took a watch out of its waistcoat-pocket, and looked at it, and then hurried on, Alice started to her feet, for it flashed across her mind that she had never before seen a rabbit with either a waistcoat-pocket, or a watch to take out of it, and burning with curiosity, she ran across the field after it, and fortunately was just in time to see it pop down a large rabbit-hole under the hedge. + +In another moment down went Alice after it, never once considering how in the world she was to get out again. + +The rabbit-hole went straight on like a tunnel for some way, and then dipped suddenly down, so suddenly that Alice had not a moment to think about stopping herself before she found herself falling down a very deep well. + +Either the well was very deep, or she fell very slowly, for she had plenty of time as she went down to look about her and to wonder what was going to happen next. First, she tried to look down and make out what she was coming to, but it was too dark to see anything; then she looked at the sides of the well, and noticed that they were filled with cupboards and book-shelves; here and there she saw maps and pictures hung upon pegs. She took down a jar from one of the shelves as she passed; it was labelled “ORANGE MARMALADE”, but to her great disappointment it was empty: she did not like to drop the jar for fear of killing somebody underneath, so managed to put it into one of the cupboards as she fell past it. + +“Well!” thought Alice to herself, “after such a fall as this, I shall think nothing of tumbling down stairs! How brave they’ll all think me at home! Why, I wouldn’t say anything about it, even if I fell off the top of the house!” (Which was very likely true.) + +Down, down, down. Would the fall never come to an end? “I wonder how many miles I’ve fallen by this time?” she said aloud. “I must be getting somewhere near the centre of the earth. Let me see: that would be four thousand miles down, I think—” (for, you see, Alice had learnt several things of this sort in her lessons in the schoolroom, and though this was not a very good opportunity for showing off her knowledge, as there was no one to listen to her, still it was good practice to say it over) “—yes, that’s about the right distance—but then I wonder what Latitude or Longitude I’ve got to?” (Alice had no idea what Latitude was, or Longitude either, but thought they were nice grand words to say.) + +Presently she began again. “I wonder if I shall fall right through the earth! How funny it’ll seem to come out among the people that walk with their heads downward! The Antipathies, I think—” (she was rather glad there was no one listening, this time, as it didn’t sound at all the right word) “—but I shall have to ask them what the name of the country is, you know. Please, Ma’am, is this New Zealand or Australia?” (and she tried to curtsey as she spoke—fancy curtseying as you’re falling through the air! Do you think you could manage it?) “And what an ignorant little girl she’ll think me for asking! No, it’ll never do to ask: perhaps I shall see it written up somewhere.” + +Down, down, down. There was nothing else to do, so Alice soon began talking again. “Dinah’ll miss me very much to-night, I should think!” (Dinah was the cat.) “I hope they’ll remember her saucer of milk at tea-time. Dinah my dear! I wish you were down here with me! There are no mice in the air, I’m afraid, but you might catch a bat, and that’s very like a mouse, you know. But do cats eat bats, I wonder?” And here Alice began to get rather sleepy, and went on saying to herself, in a dreamy sort of way, “Do cats eat bats? Do cats eat bats?” and sometimes, “Do bats eat cats?” for, you see, as she couldn’t answer either question, it didn’t much matter which way she put it. She felt that she was dozing off, and had just begun to dream that she was walking hand in hand with Dinah, and saying to her very earnestly, “Now, Dinah, tell me the truth: did you ever eat a bat?” when suddenly, thump! thump! down she came upon a heap of sticks and dry leaves, and the fall was over. + +Alice was not a bit hurt, and she jumped up on to her feet in a moment: she looked up, but it was all dark overhead; before her was another long passage, and the White Rabbit was still in sight, hurrying down it. There was not a moment to be lost: away went Alice like the wind, and was just in time to hear it say, as it turned a corner, “Oh my ears and whiskers, how late it’s getting!” She was close behind it when she turned the corner, but the Rabbit was no longer to be seen: she found herself in a long, low hall, which was lit up by a row of lamps hanging from the roof. + +There were doors all round the hall, but they were all locked; and when Alice had been all the way down one side and up the other, trying every door, she walked sadly down the middle, wondering how she was ever to get out again. + +Suddenly she came upon a little three-legged table, all made of solid glass; there was nothing on it except a tiny golden key, and Alice’s first thought was that it might belong to one of the doors of the hall; but, alas! either the locks were too large, or the key was too small, but at any rate it would not open any of them. However, on the second time round, she came upon a low curtain she had not noticed before, and behind it was a little door about fifteen inches high: she tried the little golden key in the lock, and to her great delight it fitted! + +Alice opened the door and found that it led into a small passage, not much larger than a rat-hole: she knelt down and looked along the passage into the loveliest garden you ever saw. How she longed to get out of that dark hall, and wander about among those beds of bright flowers and those cool fountains, but she could not even get her head through the doorway; “and even if my head would go through,” thought poor Alice, “it would be of very little use without my shoulders. Oh, how I wish I could shut up like a telescope! I think I could, if I only knew how to begin.” For, you see, so many out-of-the-way things had happened lately, that Alice had begun to think that very few things indeed were really impossible. + +There seemed to be no use in waiting by the little door, so she went back to the table, half hoping she might find another key on it, or at any rate a book of rules for shutting people up like telescopes: this time she found a little bottle on it, (“which certainly was not here before,” said Alice,) and round the neck of the bottle was a paper label, with the words “DRINK ME,” beautifully printed on it in large letters. + +It was all very well to say “Drink me,” but the wise little Alice was not going to do that in a hurry. “No, I’ll look first,” she said, “and see whether it’s marked ‘poison’ or not”; for she had read several nice little histories about children who had got burnt, and eaten up by wild beasts and other unpleasant things, all because they would not remember the simple rules their friends had taught them: such as, that a red-hot poker will burn you if you hold it too long; and that if you cut your finger very deeply with a knife, it usually bleeds; and she had never forgotten that, if you drink much from a bottle marked “poison,” it is almost certain to disagree with you, sooner or later. + +However, this bottle was not marked “poison,” so Alice ventured to taste it, and finding it very nice, (it had, in fact, a sort of mixed flavour of cherry-tart, custard, pine-apple, roast turkey, toffee, and hot buttered toast,) she very soon finished it off. + +* * * * * * * + + * * * * * * + +* * * * * * * +“What a curious feeling!” said Alice; “I must be shutting up like a telescope.” + +And so it was indeed: she was now only ten inches high, and her face brightened up at the thought that she was now the right size for going through the little door into that lovely garden. First, however, she waited for a few minutes to see if she was going to shrink any further: she felt a little nervous about this; “for it might end, you know,” said Alice to herself, “in my going out altogether, like a candle. I wonder what I should be like then?” And she tried to fancy what the flame of a candle is like after the candle is blown out, for she could not remember ever having seen such a thing. + +After a while, finding that nothing more happened, she decided on going into the garden at once; but, alas for poor Alice! when she got to the door, she found she had forgotten the little golden key, and when she went back to the table for it, she found she could not possibly reach it: she could see it quite plainly through the glass, and she tried her best to climb up one of the legs of the table, but it was too slippery; and when she had tired herself out with trying, the poor little thing sat down and cried. + +“Come, there’s no use in crying like that!” said Alice to herself, rather sharply; “I advise you to leave off this minute!” She generally gave herself very good advice, (though she very seldom followed it), and sometimes she scolded herself so severely as to bring tears into her eyes; and once she remembered trying to box her own ears for having cheated herself in a game of croquet she was playing against herself, for this curious child was very fond of pretending to be two people. “But it’s no use now,” thought poor Alice, “to pretend to be two people! Why, there’s hardly enough of me left to make one respectable person!” + +Soon her eye fell on a little glass box that was lying under the table: she opened it, and found in it a very small cake, on which the words “EAT ME” were beautifully marked in currants. “Well, I’ll eat it,” said Alice, “and if it makes me grow larger, I can reach the key; and if it makes me grow smaller, I can creep under the door; so either way I’ll get into the garden, and I don’t care which happens!” + +She ate a little bit, and said anxiously to herself, “Which way? Which way?”, holding her hand on the top of her head to feel which way it was growing, and she was quite surprised to find that she remained the same size: to be sure, this generally happens when one eats cake, but Alice had got so much into the way of expecting nothing but out-of-the-way things to happen, that it seemed quite dull and stupid for life to go on in the common way. + +So she set to work, and very soon finished off the cake. + +* * * * * * * + + * * * * * * + +* * * * * * * +CHAPTER II. +The Pool of Tears +“Curiouser and curiouser!” cried Alice (she was so much surprised, that for the moment she quite forgot how to speak good English); “now I’m opening out like the largest telescope that ever was! Good-bye, feet!” (for when she looked down at her feet, they seemed to be almost out of sight, they were getting so far off). “Oh, my poor little feet, I wonder who will put on your shoes and stockings for you now, dears? I’m sure I shan’t be able! I shall be a great deal too far off to trouble myself about you: you must manage the best way you can;—but I must be kind to them,” thought Alice, “or perhaps they won’t walk the way I want to go! Let me see: I’ll give them a new pair of boots every Christmas.” + +And she went on planning to herself how she would manage it. “They must go by the carrier,” she thought; “and how funny it’ll seem, sending presents to one’s own feet! And how odd the directions will look! + + Alice’s Right Foot, Esq., + Hearthrug, + near the Fender, + (with Alice’s love). +Oh dear, what nonsense I’m talking!” + +Just then her head struck against the roof of the hall: in fact she was now more than nine feet high, and she at once took up the little golden key and hurried off to the garden door. + +Poor Alice! It was as much as she could do, lying down on one side, to look through into the garden with one eye; but to get through was more hopeless than ever: she sat down and began to cry again. + +“You ought to be ashamed of yourself,” said Alice, “a great girl like you,” (she might well say this), “to go on crying in this way! Stop this moment, I tell you!” But she went on all the same, shedding gallons of tears, until there was a large pool all round her, about four inches deep and reaching half down the hall. + +After a time she heard a little pattering of feet in the distance, and she hastily dried her eyes to see what was coming. It was the White Rabbit returning, splendidly dressed, with a pair of white kid gloves in one hand and a large fan in the other: he came trotting along in a great hurry, muttering to himself as he came, “Oh! the Duchess, the Duchess! Oh! won’t she be savage if I’ve kept her waiting!” Alice felt so desperate that she was ready to ask help of any one; so, when the Rabbit came near her, she began, in a low, timid voice, “If you please, sir—” The Rabbit started violently, dropped the white kid gloves and the fan, and skurried away into the darkness as hard as he could go. + +Alice took up the fan and gloves, and, as the hall was very hot, she kept fanning herself all the time she went on talking: “Dear, dear! How queer everything is to-day! And yesterday things went on just as usual. I wonder if I’ve been changed in the night? Let me think: was I the same when I got up this morning? I almost think I can remember feeling a little different. But if I’m not the same, the next question is, Who in the world am I? Ah, that’s the great puzzle!” And she began thinking over all the children she knew that were of the same age as herself, to see if she could have been changed for any of them. + +“I’m sure I’m not Ada,” she said, “for her hair goes in such long ringlets, and mine doesn’t go in ringlets at all; and I’m sure I can’t be Mabel, for I know all sorts of things, and she, oh! she knows such a very little! Besides, she’s she, and I’m I, and—oh dear, how puzzling it all is! I’ll try if I know all the things I used to know. Let me see: four times five is twelve, and four times six is thirteen, and four times seven is—oh dear! I shall never get to twenty at that rate! However, the Multiplication Table doesn’t signify: let’s try Geography. London is the capital of Paris, and Paris is the capital of Rome, and Rome—no, that’s all wrong, I’m certain! I must have been changed for Mabel! I’ll try and say ‘How doth the little—’” and she crossed her hands on her lap as if she were saying lessons, and began to repeat it, but her voice sounded hoarse and strange, and the words did not come the same as they used to do:— + +“How doth the little crocodile + Improve his shining tail, +And pour the waters of the Nile + On every golden scale! + +“How cheerfully he seems to grin, + How neatly spread his claws, +And welcome little fishes in + With gently smiling jaws!” + +“I’m sure those are not the right words,” said poor Alice, and her eyes filled with tears again as she went on, “I must be Mabel after all, and I shall have to go and live in that poky little house, and have next to no toys to play with, and oh! ever so many lessons to learn! No, I’ve made up my mind about it; if I’m Mabel, I’ll stay down here! It’ll be no use their putting their heads down and saying ‘Come up again, dear!’ I shall only look up and say ‘Who am I then? Tell me that first, and then, if I like being that person, I’ll come up: if not, I’ll stay down here till I’m somebody else’—but, oh dear!” cried Alice, with a sudden burst of tears, “I do wish they would put their heads down! I am so very tired of being all alone here!” + +As she said this she looked down at her hands, and was surprised to see that she had put on one of the Rabbit’s little white kid gloves while she was talking. “How can I have done that?” she thought. “I must be growing small again.” She got up and went to the table to measure herself by it, and found that, as nearly as she could guess, she was now about two feet high, and was going on shrinking rapidly: she soon found out that the cause of this was the fan she was holding, and she dropped it hastily, just in time to avoid shrinking away altogether. + +“That was a narrow escape!” said Alice, a good deal frightened at the sudden change, but very glad to find herself still in existence; “and now for the garden!” and she ran with all speed back to the little door: but, alas! the little door was shut again, and the little golden key was lying on the glass table as before, “and things are worse than ever,” thought the poor child, “for I never was so small as this before, never! And I declare it’s too bad, that it is!” + +As she said these words her foot slipped, and in another moment, splash! she was up to her chin in salt water. Her first idea was that she had somehow fallen into the sea, “and in that case I can go back by railway,” she said to herself. (Alice had been to the seaside once in her life, and had come to the general conclusion, that wherever you go to on the English coast you find a number of bathing machines in the sea, some children digging in the sand with wooden spades, then a row of lodging houses, and behind them a railway station.) However, she soon made out that she was in the pool of tears which she had wept when she was nine feet high. + +“I wish I hadn’t cried so much!” said Alice, as she swam about, trying to find her way out. “I shall be punished for it now, I suppose, by being drowned in my own tears! That will be a queer thing, to be sure! However, everything is queer to-day.” + +Just then she heard something splashing about in the pool a little way off, and she swam nearer to make out what it was: at first she thought it must be a walrus or hippopotamus, but then she remembered how small she was now, and she soon made out that it was only a mouse that had slipped in like herself. + +“Would it be of any use, now,” thought Alice, “to speak to this mouse? Everything is so out-of-the-way down here, that I should think very likely it can talk: at any rate, there’s no harm in trying.” So she began: “O Mouse, do you know the way out of this pool? I am very tired of swimming about here, O Mouse!” (Alice thought this must be the right way of speaking to a mouse: she had never done such a thing before, but she remembered having seen in her brother’s Latin Grammar, “A mouse—of a mouse—to a mouse—a mouse—O mouse!”) The Mouse looked at her rather inquisitively, and seemed to her to wink with one of its little eyes, but it said nothing. + +“Perhaps it doesn’t understand English,” thought Alice; “I daresay it’s a French mouse, come over with William the Conqueror.” (For, with all her knowledge of history, Alice had no very clear notion how long ago anything had happened.) So she began again: “Où est ma chatte?” which was the first sentence in her French lesson-book. The Mouse gave a sudden leap out of the water, and seemed to quiver all over with fright. “Oh, I beg your pardon!” cried Alice hastily, afraid that she had hurt the poor animal’s feelings. “I quite forgot you didn’t like cats.” + +“Not like cats!” cried the Mouse, in a shrill, passionate voice. “Would you like cats if you were me?” + +“Well, perhaps not,” said Alice in a soothing tone: “don’t be angry about it. And yet I wish I could show you our cat Dinah: I think you’d take a fancy to cats if you could only see her. She is such a dear quiet thing,” Alice went on, half to herself, as she swam lazily about in the pool, “and she sits purring so nicely by the fire, licking her paws and washing her face—and she is such a nice soft thing to nurse—and she’s such a capital one for catching mice—oh, I beg your pardon!” cried Alice again, for this time the Mouse was bristling all over, and she felt certain it must be really offended. “We won’t talk about her any more if you’d rather not.” + +“We indeed!” cried the Mouse, who was trembling down to the end of his tail. “As if I would talk on such a subject! Our family always hated cats: nasty, low, vulgar things! Don’t let me hear the name again!” + +“I won’t indeed!” said Alice, in a great hurry to change the subject of conversation. “Are you—are you fond—of—of dogs?” The Mouse did not answer, so Alice went on eagerly: “There is such a nice little dog near our house I should like to show you! A little bright-eyed terrier, you know, with oh, such long curly brown hair! And it’ll fetch things when you throw them, and it’ll sit up and beg for its dinner, and all sorts of things—I can’t remember half of them—and it belongs to a farmer, you know, and he says it’s so useful, it’s worth a hundred pounds! He says it kills all the rats and—oh dear!” cried Alice in a sorrowful tone, “I’m afraid I’ve offended it again!” For the Mouse was swimming away from her as hard as it could go, and making quite a commotion in the pool as it went. + +So she called softly after it, “Mouse dear! Do come back again, and we won’t talk about cats or dogs either, if you don’t like them!” When the Mouse heard this, it turned round and swam slowly back to her: its face was quite pale (with passion, Alice thought), and it said in a low trembling voice, “Let us get to the shore, and then I’ll tell you my history, and you’ll understand why it is I hate cats and dogs.” + +It was high time to go, for the pool was getting quite crowded with the birds and animals that had fallen into it: there were a Duck and a Dodo, a Lory and an Eaglet, and several other curious creatures. Alice led the way, and the whole party swam to the shore. + +CHAPTER III. +A Caucus-Race and a Long Tale +They were indeed a queer-looking party that assembled on the bank—the birds with draggled feathers, the animals with their fur clinging close to them, and all dripping wet, cross, and uncomfortable. + +The first question of course was, how to get dry again: they had a consultation about this, and after a few minutes it seemed quite natural to Alice to find herself talking familiarly with them, as if she had known them all her life. Indeed, she had quite a long argument with the Lory, who at last turned sulky, and would only say, “I am older than you, and must know better;” and this Alice would not allow without knowing how old it was, and, as the Lory positively refused to tell its age, there was no more to be said. + +At last the Mouse, who seemed to be a person of authority among them, called out, “Sit down, all of you, and listen to me! I’ll soon make you dry enough!” They all sat down at once, in a large ring, with the Mouse in the middle. Alice kept her eyes anxiously fixed on it, for she felt sure she would catch a bad cold if she did not get dry very soon. + +“Ahem!” said the Mouse with an important air, “are you all ready? This is the driest thing I know. Silence all round, if you please! ‘William the Conqueror, whose cause was favoured by the pope, was soon submitted to by the English, who wanted leaders, and had been of late much accustomed to usurpation and conquest. Edwin and Morcar, the earls of Mercia and Northumbria—’” + +“Ugh!” said the Lory, with a shiver. + +“I beg your pardon!” said the Mouse, frowning, but very politely: “Did you speak?” + +“Not I!” said the Lory hastily. + +“I thought you did,” said the Mouse. “—I proceed. ‘Edwin and Morcar, the earls of Mercia and Northumbria, declared for him: and even Stigand, the patriotic archbishop of Canterbury, found it advisable—’” + +“Found what?” said the Duck. + +“Found it,” the Mouse replied rather crossly: “of course you know what ‘it’ means.” + +“I know what ‘it’ means well enough, when I find a thing,” said the Duck: “it’s generally a frog or a worm. The question is, what did the archbishop find?” + +The Mouse did not notice this question, but hurriedly went on, “‘—found it advisable to go with Edgar Atheling to meet William and offer him the crown. William’s conduct at first was moderate. But the insolence of his Normans—’ How are you getting on now, my dear?” it continued, turning to Alice as it spoke. + +“As wet as ever,” said Alice in a melancholy tone: “it doesn’t seem to dry me at all.” + +“In that case,” said the Dodo solemnly, rising to its feet, “I move that the meeting adjourn, for the immediate adoption of more energetic remedies—” + +“Speak English!” said the Eaglet. “I don’t know the meaning of half those long words, and, what’s more, I don’t believe you do either!” And the Eaglet bent down its head to hide a smile: some of the other birds tittered audibly. + +“What I was going to say,” said the Dodo in an offended tone, “was, that the best thing to get us dry would be a Caucus-race.” + +“What is a Caucus-race?” said Alice; not that she wanted much to know, but the Dodo had paused as if it thought that somebody ought to speak, and no one else seemed inclined to say anything. + +“Why,” said the Dodo, “the best way to explain it is to do it.” (And, as you might like to try the thing yourself, some winter day, I will tell you how the Dodo managed it.) + +First it marked out a race-course, in a sort of circle, (“the exact shape doesn’t matter,” it said,) and then all the party were placed along the course, here and there. There was no “One, two, three, and away,” but they began running when they liked, and left off when they liked, so that it was not easy to know when the race was over. However, when they had been running half an hour or so, and were quite dry again, the Dodo suddenly called out “The race is over!” and they all crowded round it, panting, and asking, “But who has won?” + +This question the Dodo could not answer without a great deal of thought, and it sat for a long time with one finger pressed upon its forehead (the position in which you usually see Shakespeare, in the pictures of him), while the rest waited in silence. At last the Dodo said, “Everybody has won, and all must have prizes.” + +“But who is to give the prizes?” quite a chorus of voices asked. + +“Why, she, of course,” said the Dodo, pointing to Alice with one finger; and the whole party at once crowded round her, calling out in a confused way, “Prizes! Prizes!” + +Alice had no idea what to do, and in despair she put her hand in her pocket, and pulled out a box of comfits, (luckily the salt water had not got into it), and handed them round as prizes. There was exactly one a-piece, all round. + +“But she must have a prize herself, you know,” said the Mouse. + +“Of course,” the Dodo replied very gravely. “What else have you got in your pocket?” he went on, turning to Alice. + +“Only a thimble,” said Alice sadly. + +“Hand it over here,” said the Dodo. + +Then they all crowded round her once more, while the Dodo solemnly presented the thimble, saying “We beg your acceptance of this elegant thimble;” and, when it had finished this short speech, they all cheered. + +Alice thought the whole thing very absurd, but they all looked so grave that she did not dare to laugh; and, as she could not think of anything to say, she simply bowed, and took the thimble, looking as solemn as she could. + +The next thing was to eat the comfits: this caused some noise and confusion, as the large birds complained that they could not taste theirs, and the small ones choked and had to be patted on the back. However, it was over at last, and they sat down again in a ring, and begged the Mouse to tell them something more. + +“You promised to tell me your history, you know,” said Alice, “and why it is you hate—C and D,” she added in a whisper, half afraid that it would be offended again. + +“Mine is a long and a sad tale!” said the Mouse, turning to Alice, and sighing. + +“It is a long tail, certainly,” said Alice, looking down with wonder at the Mouse’s tail; “but why do you call it sad?” And she kept on puzzling about it while the Mouse was speaking, so that her idea of the tale was something like this:— + + “Fury said to a + mouse, That he + met in the + house, + ‘Let us + both go to + law: I will + prosecute + you.—Come, + I’ll take no + denial; We + must have a + trial: For + really this + morning I’ve + nothing + to do.’ + Said the + mouse to the + cur, ‘Such + a trial, + dear sir, + With + no jury + or judge, + would be + wasting + our + breath.’ + ‘I’ll be + judge, I’ll + be jury,’ + Said + cunning + old Fury: + ‘I’ll + try the + whole + cause, + and + condemn + you + to + death.’” +“You are not attending!” said the Mouse to Alice severely. “What are you thinking of?” + +“I beg your pardon,” said Alice very humbly: “you had got to the fifth bend, I think?” + +“I had not!” cried the Mouse, sharply and very angrily. + +“A knot!” said Alice, always ready to make herself useful, and looking anxiously about her. “Oh, do let me help to undo it!” + +“I shall do nothing of the sort,” said the Mouse, getting up and walking away. “You insult me by talking such nonsense!” + +“I didn’t mean it!” pleaded poor Alice. “But you’re so easily offended, you know!” + +The Mouse only growled in reply. + +“Please come back and finish your story!” Alice called after it; and the others all joined in chorus, “Yes, please do!” but the Mouse only shook its head impatiently, and walked a little quicker. + +“What a pity it wouldn’t stay!” sighed the Lory, as soon as it was quite out of sight; and an old Crab took the opportunity of saying to her daughter “Ah, my dear! Let this be a lesson to you never to lose your temper!” “Hold your tongue, Ma!” said the young Crab, a little snappishly. “You’re enough to try the patience of an oyster!” + +“I wish I had our Dinah here, I know I do!” said Alice aloud, addressing nobody in particular. “She’d soon fetch it back!” + +“And who is Dinah, if I might venture to ask the question?” said the Lory. + +Alice replied eagerly, for she was always ready to talk about her pet: “Dinah’s our cat. And she’s such a capital one for catching mice you can’t think! And oh, I wish you could see her after the birds! Why, she’ll eat a little bird as soon as look at it!” + +This speech caused a remarkable sensation among the party. Some of the birds hurried off at once: one old Magpie began wrapping itself up very carefully, remarking, “I really must be getting home; the night-air doesn’t suit my throat!” and a Canary called out in a trembling voice to its children, “Come away, my dears! It’s high time you were all in bed!” On various pretexts they all moved off, and Alice was soon left alone. + +“I wish I hadn’t mentioned Dinah!” she said to herself in a melancholy tone. “Nobody seems to like her, down here, and I’m sure she’s the best cat in the world! Oh, my dear Dinah! I wonder if I shall ever see you any more!” And here poor Alice began to cry again, for she felt very lonely and low-spirited. In a little while, however, she again heard a little pattering of footsteps in the distance, and she looked up eagerly, half hoping that the Mouse had changed his mind, and was coming back to finish his story. + +CHAPTER IV. +The Rabbit Sends in a Little Bill +It was the White Rabbit, trotting slowly back again, and looking anxiously about as it went, as if it had lost something; and she heard it muttering to itself “The Duchess! The Duchess! Oh my dear paws! Oh my fur and whiskers! She’ll get me executed, as sure as ferrets are ferrets! Where can I have dropped them, I wonder?” Alice guessed in a moment that it was looking for the fan and the pair of white kid gloves, and she very good-naturedly began hunting about for them, but they were nowhere to be seen—everything seemed to have changed since her swim in the pool, and the great hall, with the glass table and the little door, had vanished completely. + +Very soon the Rabbit noticed Alice, as she went hunting about, and called out to her in an angry tone, “Why, Mary Ann, what are you doing out here? Run home this moment, and fetch me a pair of gloves and a fan! Quick, now!” And Alice was so much frightened that she ran off at once in the direction it pointed to, without trying to explain the mistake it had made. + +“He took me for his housemaid,” she said to herself as she ran. “How surprised he’ll be when he finds out who I am! But I’d better take him his fan and gloves—that is, if I can find them.” As she said this, she came upon a neat little house, on the door of which was a bright brass plate with the name “W. RABBIT,” engraved upon it. She went in without knocking, and hurried upstairs, in great fear lest she should meet the real Mary Ann, and be turned out of the house before she had found the fan and gloves. + +“How queer it seems,” Alice said to herself, “to be going messages for a rabbit! I suppose Dinah’ll be sending me on messages next!” And she began fancying the sort of thing that would happen: “‘Miss Alice! Come here directly, and get ready for your walk!’ ‘Coming in a minute, nurse! But I’ve got to see that the mouse doesn’t get out.’ Only I don’t think,” Alice went on, “that they’d let Dinah stop in the house if it began ordering people about like that!” + +By this time she had found her way into a tidy little room with a table in the window, and on it (as she had hoped) a fan and two or three pairs of tiny white kid gloves: she took up the fan and a pair of the gloves, and was just going to leave the room, when her eye fell upon a little bottle that stood near the looking-glass. There was no label this time with the words “DRINK ME,” but nevertheless she uncorked it and put it to her lips. “I know something interesting is sure to happen,” she said to herself, “whenever I eat or drink anything; so I’ll just see what this bottle does. I do hope it’ll make me grow large again, for really I’m quite tired of being such a tiny little thing!” + +It did so indeed, and much sooner than she had expected: before she had drunk half the bottle, she found her head pressing against the ceiling, and had to stoop to save her neck from being broken. She hastily put down the bottle, saying to herself “That’s quite enough—I hope I shan’t grow any more—As it is, I can’t get out at the door—I do wish I hadn’t drunk quite so much!” + +Alas! it was too late to wish that! She went on growing, and growing, and very soon had to kneel down on the floor: in another minute there was not even room for this, and she tried the effect of lying down with one elbow against the door, and the other arm curled round her head. Still she went on growing, and, as a last resource, she put one arm out of the window, and one foot up the chimney, and said to herself “Now I can do no more, whatever happens. What will become of me?” + +Luckily for Alice, the little magic bottle had now had its full effect, and she grew no larger: still it was very uncomfortable, and, as there seemed to be no sort of chance of her ever getting out of the room again, no wonder she felt unhappy. + +“It was much pleasanter at home,” thought poor Alice, “when one wasn’t always growing larger and smaller, and being ordered about by mice and rabbits. I almost wish I hadn’t gone down that rabbit-hole—and yet—and yet—it’s rather curious, you know, this sort of life! I do wonder what can have happened to me! When I used to read fairy-tales, I fancied that kind of thing never happened, and now here I am in the middle of one! There ought to be a book written about me, that there ought! And when I grow up, I’ll write one—but I’m grown up now,” she added in a sorrowful tone; “at least there’s no room to grow up any more here.” + +“But then,” thought Alice, “shall I never get any older than I am now? That’ll be a comfort, one way—never to be an old woman—but then—always to have lessons to learn! Oh, I shouldn’t like that!” + +“Oh, you foolish Alice!” she answered herself. “How can you learn lessons in here? Why, there’s hardly room for you, and no room at all for any lesson-books!” + +And so she went on, taking first one side and then the other, and making quite a conversation of it altogether; but after a few minutes she heard a voice outside, and stopped to listen. + +“Mary Ann! Mary Ann!” said the voice. “Fetch me my gloves this moment!” Then came a little pattering of feet on the stairs. Alice knew it was the Rabbit coming to look for her, and she trembled till she shook the house, quite forgetting that she was now about a thousand times as large as the Rabbit, and had no reason to be afraid of it. + +Presently the Rabbit came up to the door, and tried to open it; but, as the door opened inwards, and Alice’s elbow was pressed hard against it, that attempt proved a failure. Alice heard it say to itself “Then I’ll go round and get in at the window.” + +“That you won’t!” thought Alice, and, after waiting till she fancied she heard the Rabbit just under the window, she suddenly spread out her hand, and made a snatch in the air. She did not get hold of anything, but she heard a little shriek and a fall, and a crash of broken glass, from which she concluded that it was just possible it had fallen into a cucumber-frame, or something of the sort. + +Next came an angry voice—the Rabbit’s—“Pat! Pat! Where are you?” And then a voice she had never heard before, “Sure then I’m here! Digging for apples, yer honour!” + +“Digging for apples, indeed!” said the Rabbit angrily. “Here! Come and help me out of this!” (Sounds of more broken glass.) + +“Now tell me, Pat, what’s that in the window?” + +“Sure, it’s an arm, yer honour!” (He pronounced it “arrum.”) + +“An arm, you goose! Who ever saw one that size? Why, it fills the whole window!” + +“Sure, it does, yer honour: but it’s an arm for all that.” + +“Well, it’s got no business there, at any rate: go and take it away!” + +There was a long silence after this, and Alice could only hear whispers now and then; such as, “Sure, I don’t like it, yer honour, at all, at all!” “Do as I tell you, you coward!” and at last she spread out her hand again, and made another snatch in the air. This time there were two little shrieks, and more sounds of broken glass. “What a number of cucumber-frames there must be!” thought Alice. “I wonder what they’ll do next! As for pulling me out of the window, I only wish they could! I’m sure I don’t want to stay in here any longer!” + +She waited for some time without hearing anything more: at last came a rumbling of little cartwheels, and the sound of a good many voices all talking together: she made out the words: “Where’s the other ladder?—Why, I hadn’t to bring but one; Bill’s got the other—Bill! fetch it here, lad!—Here, put ’em up at this corner—No, tie ’em together first—they don’t reach half high enough yet—Oh! they’ll do well enough; don’t be particular—Here, Bill! catch hold of this rope—Will the roof bear?—Mind that loose slate—Oh, it’s coming down! Heads below!” (a loud crash)—“Now, who did that?—It was Bill, I fancy—Who’s to go down the chimney?—Nay, I shan’t! You do it!—That I won’t, then!—Bill’s to go down—Here, Bill! the master says you’re to go down the chimney!” + +“Oh! So Bill’s got to come down the chimney, has he?” said Alice to herself. “Shy, they seem to put everything upon Bill! I wouldn’t be in Bill’s place for a good deal: this fireplace is narrow, to be sure; but I think I can kick a little!” + +She drew her foot as far down the chimney as she could, and waited till she heard a little animal (she couldn’t guess of what sort it was) scratching and scrambling about in the chimney close above her: then, saying to herself “This is Bill,” she gave one sharp kick, and waited to see what would happen next. + +The first thing she heard was a general chorus of “There goes Bill!” then the Rabbit’s voice along—“Catch him, you by the hedge!” then silence, and then another confusion of voices—“Hold up his head—Brandy now—Don’t choke him—How was it, old fellow? What happened to you? Tell us all about it!” + +Last came a little feeble, squeaking voice, (“That’s Bill,” thought Alice,) “Well, I hardly know—No more, thank ye; I’m better now—but I’m a deal too flustered to tell you—all I know is, something comes at me like a Jack-in-the-box, and up I goes like a sky-rocket!” + +“So you did, old fellow!” said the others. + +“We must burn the house down!” said the Rabbit’s voice; and Alice called out as loud as she could, “If you do, I’ll set Dinah at you!” + +There was a dead silence instantly, and Alice thought to herself, “I wonder what they will do next! If they had any sense, they’d take the roof off.” After a minute or two, they began moving about again, and Alice heard the Rabbit say, “A barrowful will do, to begin with.” + +“A barrowful of what?” thought Alice; but she had not long to doubt, for the next moment a shower of little pebbles came rattling in at the window, and some of them hit her in the face. “I’ll put a stop to this,” she said to herself, and shouted out, “You’d better not do that again!” which produced another dead silence. + +Alice noticed with some surprise that the pebbles were all turning into little cakes as they lay on the floor, and a bright idea came into her head. “If I eat one of these cakes,” she thought, “it’s sure to make some change in my size; and as it can’t possibly make me larger, it must make me smaller, I suppose.” + +So she swallowed one of the cakes, and was delighted to find that she began shrinking directly. As soon as she was small enough to get through the door, she ran out of the house, and found quite a crowd of little animals and birds waiting outside. The poor little Lizard, Bill, was in the middle, being held up by two guinea-pigs, who were giving it something out of a bottle. They all made a rush at Alice the moment she appeared; but she ran off as hard as she could, and soon found herself safe in a thick wood. + +“The first thing I’ve got to do,” said Alice to herself, as she wandered about in the wood, “is to grow to my right size again; and the second thing is to find my way into that lovely garden. I think that will be the best plan.” + +It sounded an excellent plan, no doubt, and very neatly and simply arranged; the only difficulty was, that she had not the smallest idea how to set about it; and while she was peering about anxiously among the trees, a little sharp bark just over her head made her look up in a great hurry. + +An enormous puppy was looking down at her with large round eyes, and feebly stretching out one paw, trying to touch her. “Poor little thing!” said Alice, in a coaxing tone, and she tried hard to whistle to it; but she was terribly frightened all the time at the thought that it might be hungry, in which case it would be very likely to eat her up in spite of all her coaxing. + +Hardly knowing what she did, she picked up a little bit of stick, and held it out to the puppy; whereupon the puppy jumped into the air off all its feet at once, with a yelp of delight, and rushed at the stick, and made believe to worry it; then Alice dodged behind a great thistle, to keep herself from being run over; and the moment she appeared on the other side, the puppy made another rush at the stick, and tumbled head over heels in its hurry to get hold of it; then Alice, thinking it was very like having a game of play with a cart-horse, and expecting every moment to be trampled under its feet, ran round the thistle again; then the puppy began a series of short charges at the stick, running a very little way forwards each time and a long way back, and barking hoarsely all the while, till at last it sat down a good way off, panting, with its tongue hanging out of its mouth, and its great eyes half shut. + +This seemed to Alice a good opportunity for making her escape; so she set off at once, and ran till she was quite tired and out of breath, and till the puppy’s bark sounded quite faint in the distance. + +“And yet what a dear little puppy it was!” said Alice, as she leant against a buttercup to rest herself, and fanned herself with one of the leaves: “I should have liked teaching it tricks very much, if—if I’d only been the right size to do it! Oh dear! I’d nearly forgotten that I’ve got to grow up again! Let me see—how is it to be managed? I suppose I ought to eat or drink something or other; but the great question is, what?” + +The great question certainly was, what? Alice looked all round her at the flowers and the blades of grass, but she did not see anything that looked like the right thing to eat or drink under the circumstances. There was a large mushroom growing near her, about the same height as herself; and when she had looked under it, and on both sides of it, and behind it, it occurred to her that she might as well look and see what was on the top of it. + +She stretched herself up on tiptoe, and peeped over the edge of the mushroom, and her eyes immediately met those of a large blue caterpillar, that was sitting on the top with its arms folded, quietly smoking a long hookah, and taking not the smallest notice of her or of anything else. + +CHAPTER V. +Advice from a Caterpillar +The Caterpillar and Alice looked at each other for some time in silence: at last the Caterpillar took the hookah out of its mouth, and addressed her in a languid, sleepy voice. + +“Who are you?” said the Caterpillar. + +This was not an encouraging opening for a conversation. Alice replied, rather shyly, “I—I hardly know, sir, just at present—at least I know who I was when I got up this morning, but I think I must have been changed several times since then.” + +“What do you mean by that?” said the Caterpillar sternly. “Explain yourself!” + +“I can’t explain myself, I’m afraid, sir,” said Alice, “because I’m not myself, you see.” + +“I don’t see,” said the Caterpillar. + +“I’m afraid I can’t put it more clearly,” Alice replied very politely, “for I can’t understand it myself to begin with; and being so many different sizes in a day is very confusing.” + +“It isn’t,” said the Caterpillar. + +“Well, perhaps you haven’t found it so yet,” said Alice; “but when you have to turn into a chrysalis—you will some day, you know—and then after that into a butterfly, I should think you’ll feel it a little queer, won’t you?” + +“Not a bit,” said the Caterpillar. + +“Well, perhaps your feelings may be different,” said Alice; “all I know is, it would feel very queer to me.” + +“You!” said the Caterpillar contemptuously. “Who are you?” + +Which brought them back again to the beginning of the conversation. Alice felt a little irritated at the Caterpillar’s making such very short remarks, and she drew herself up and said, very gravely, “I think, you ought to tell me who you are, first.” + +“Why?” said the Caterpillar. + +Here was another puzzling question; and as Alice could not think of any good reason, and as the Caterpillar seemed to be in a very unpleasant state of mind, she turned away. + +“Come back!” the Caterpillar called after her. “I’ve something important to say!” + +This sounded promising, certainly: Alice turned and came back again. + +“Keep your temper,” said the Caterpillar. + +“Is that all?” said Alice, swallowing down her anger as well as she could. + +“No,” said the Caterpillar. + +Alice thought she might as well wait, as she had nothing else to do, and perhaps after all it might tell her something worth hearing. For some minutes it puffed away without speaking, but at last it unfolded its arms, took the hookah out of its mouth again, and said, “So you think you’re changed, do you?” + +“I’m afraid I am, sir,” said Alice; “I can’t remember things as I used—and I don’t keep the same size for ten minutes together!” + +“Can’t remember what things?” said the Caterpillar. + +“Well, I’ve tried to say “How doth the little busy bee,” but it all came different!” Alice replied in a very melancholy voice. + +“Repeat, “You are old, Father William,’” said the Caterpillar. + +Alice folded her hands, and began:— + +“You are old, Father William,” the young man said, + “And your hair has become very white; +And yet you incessantly stand on your head— + Do you think, at your age, it is right?” + +“In my youth,” Father William replied to his son, + “I feared it might injure the brain; +But, now that I’m perfectly sure I have none, + Why, I do it again and again.” + +“You are old,” said the youth, “as I mentioned before, + And have grown most uncommonly fat; +Yet you turned a back-somersault in at the door— + Pray, what is the reason of that?” + +“In my youth,” said the sage, as he shook his grey locks, + “I kept all my limbs very supple +By the use of this ointment—one shilling the box— + Allow me to sell you a couple?” + +“You are old,” said the youth, “and your jaws are too weak + For anything tougher than suet; +Yet you finished the goose, with the bones and the beak— + Pray, how did you manage to do it?” + +“In my youth,” said his father, “I took to the law, + And argued each case with my wife; +And the muscular strength, which it gave to my jaw, + Has lasted the rest of my life.” + +“You are old,” said the youth, “one would hardly suppose + That your eye was as steady as ever; +Yet you balanced an eel on the end of your nose— + What made you so awfully clever?” + +“I have answered three questions, and that is enough,” + Said his father; “don’t give yourself airs! +Do you think I can listen all day to such stuff? + Be off, or I’ll kick you down stairs!” + +“That is not said right,” said the Caterpillar. + +“Not quite right, I’m afraid,” said Alice, timidly; “some of the words have got altered.” + +“It is wrong from beginning to end,” said the Caterpillar decidedly, and there was silence for some minutes. + +The Caterpillar was the first to speak. + +“What size do you want to be?” it asked. + +“Oh, I’m not particular as to size,” Alice hastily replied; “only one doesn’t like changing so often, you know.” + +“I don’t know,” said the Caterpillar. + +Alice said nothing: she had never been so much contradicted in her life before, and she felt that she was losing her temper. + +“Are you content now?” said the Caterpillar. + +“Well, I should like to be a little larger, sir, if you wouldn’t mind,” said Alice: “three inches is such a wretched height to be.” + +“It is a very good height indeed!” said the Caterpillar angrily, rearing itself upright as it spoke (it was exactly three inches high). + +“But I’m not used to it!” pleaded poor Alice in a piteous tone. And she thought of herself, “I wish the creatures wouldn’t be so easily offended!” + +“You’ll get used to it in time,” said the Caterpillar; and it put the hookah into its mouth and began smoking again. + +This time Alice waited patiently until it chose to speak again. In a minute or two the Caterpillar took the hookah out of its mouth and yawned once or twice, and shook itself. Then it got down off the mushroom, and crawled away in the grass, merely remarking as it went, “One side will make you grow taller, and the other side will make you grow shorter.” + +“One side of what? The other side of what?” thought Alice to herself. + +“Of the mushroom,” said the Caterpillar, just as if she had asked it aloud; and in another moment it was out of sight. + +Alice remained looking thoughtfully at the mushroom for a minute, trying to make out which were the two sides of it; and as it was perfectly round, she found this a very difficult question. However, at last she stretched her arms round it as far as they would go, and broke off a bit of the edge with each hand. + +“And now which is which?” she said to herself, and nibbled a little of the right-hand bit to try the effect: the next moment she felt a violent blow underneath her chin: it had struck her foot! + +She was a good deal frightened by this very sudden change, but she felt that there was no time to be lost, as she was shrinking rapidly; so she set to work at once to eat some of the other bit. Her chin was pressed so closely against her foot, that there was hardly room to open her mouth; but she did it at last, and managed to swallow a morsel of the lefthand bit. + +* * * * * * * + + * * * * * * + +* * * * * * * +“Come, my head’s free at last!” said Alice in a tone of delight, which changed into alarm in another moment, when she found that her shoulders were nowhere to be found: all she could see, when she looked down, was an immense length of neck, which seemed to rise like a stalk out of a sea of green leaves that lay far below her. + +“What can all that green stuff be?” said Alice. “And where have my shoulders got to? And oh, my poor hands, how is it I can’t see you?” She was moving them about as she spoke, but no result seemed to follow, except a little shaking among the distant green leaves. + +As there seemed to be no chance of getting her hands up to her head, she tried to get her head down to them, and was delighted to find that her neck would bend about easily in any direction, like a serpent. She had just succeeded in curving it down into a graceful zigzag, and was going to dive in among the leaves, which she found to be nothing but the tops of the trees under which she had been wandering, when a sharp hiss made her draw back in a hurry: a large pigeon had flown into her face, and was beating her violently with its wings. + +“Serpent!” screamed the Pigeon. + +“I’m not a serpent!” said Alice indignantly. “Let me alone!” + +“Serpent, I say again!” repeated the Pigeon, but in a more subdued tone, and added with a kind of sob, “I’ve tried every way, and nothing seems to suit them!” + +“I haven’t the least idea what you’re talking about,” said Alice. + +“I’ve tried the roots of trees, and I’ve tried banks, and I’ve tried hedges,” the Pigeon went on, without attending to her; “but those serpents! There’s no pleasing them!” + +Alice was more and more puzzled, but she thought there was no use in saying anything more till the Pigeon had finished. + +“As if it wasn’t trouble enough hatching the eggs,” said the Pigeon; “but I must be on the look-out for serpents night and day! Why, I haven’t had a wink of sleep these three weeks!” + +“I’m very sorry you’ve been annoyed,” said Alice, who was beginning to see its meaning. + +“And just as I’d taken the highest tree in the wood,” continued the Pigeon, raising its voice to a shriek, “and just as I was thinking I should be free of them at last, they must needs come wriggling down from the sky! Ugh, Serpent!” + +“But I’m not a serpent, I tell you!” said Alice. “I’m a—I’m a—” + +“Well! What are you?” said the Pigeon. “I can see you’re trying to invent something!” + +“I—I’m a little girl,” said Alice, rather doubtfully, as she remembered the number of changes she had gone through that day. + +“A likely story indeed!” said the Pigeon in a tone of the deepest contempt. “I’ve seen a good many little girls in my time, but never one with such a neck as that! No, no! You’re a serpent; and there’s no use denying it. I suppose you’ll be telling me next that you never tasted an egg!” + +“I have tasted eggs, certainly,” said Alice, who was a very truthful child; “but little girls eat eggs quite as much as serpents do, you know.” + +“I don’t believe it,” said the Pigeon; “but if they do, why then they’re a kind of serpent, that’s all I can say.” + +This was such a new idea to Alice, that she was quite silent for a minute or two, which gave the Pigeon the opportunity of adding, “You’re looking for eggs, I know that well enough; and what does it matter to me whether you’re a little girl or a serpent?” + +“It matters a good deal to me,” said Alice hastily; “but I’m not looking for eggs, as it happens; and if I was, I shouldn’t want yours: I don’t like them raw.” + +“Well, be off, then!” said the Pigeon in a sulky tone, as it settled down again into its nest. Alice crouched down among the trees as well as she could, for her neck kept getting entangled among the branches, and every now and then she had to stop and untwist it. After a while she remembered that she still held the pieces of mushroom in her hands, and she set to work very carefully, nibbling first at one and then at the other, and growing sometimes taller and sometimes shorter, until she had succeeded in bringing herself down to her usual height. + +It was so long since she had been anything near the right size, that it felt quite strange at first; but she got used to it in a few minutes, and began talking to herself, as usual. “Come, there’s half my plan done now! How puzzling all these changes are! I’m never sure what I’m going to be, from one minute to another! However, I’ve got back to my right size: the next thing is, to get into that beautiful garden—how is that to be done, I wonder?” As she said this, she came suddenly upon an open place, with a little house in it about four feet high. “Whoever lives there,” thought Alice, “it’ll never do to come upon them this size: why, I should frighten them out of their wits!” So she began nibbling at the righthand bit again, and did not venture to go near the house till she had brought herself down to nine inches high. + +CHAPTER VI. +Pig and Pepper +For a minute or two she stood looking at the house, and wondering what to do next, when suddenly a footman in livery came running out of the wood—(she considered him to be a footman because he was in livery: otherwise, judging by his face only, she would have called him a fish)—and rapped loudly at the door with his knuckles. It was opened by another footman in livery, with a round face, and large eyes like a frog; and both footmen, Alice noticed, had powdered hair that curled all over their heads. She felt very curious to know what it was all about, and crept a little way out of the wood to listen. + +The Fish-Footman began by producing from under his arm a great letter, nearly as large as himself, and this he handed over to the other, saying, in a solemn tone, “For the Duchess. An invitation from the Queen to play croquet.” The Frog-Footman repeated, in the same solemn tone, only changing the order of the words a little, “From the Queen. An invitation for the Duchess to play croquet.” + +Then they both bowed low, and their curls got entangled together. + +Alice laughed so much at this, that she had to run back into the wood for fear of their hearing her; and when she next peeped out the Fish-Footman was gone, and the other was sitting on the ground near the door, staring stupidly up into the sky. + +Alice went timidly up to the door, and knocked. + +“There’s no sort of use in knocking,” said the Footman, “and that for two reasons. First, because I’m on the same side of the door as you are; secondly, because they’re making such a noise inside, no one could possibly hear you.” And certainly there was a most extraordinary noise going on within—a constant howling and sneezing, and every now and then a great crash, as if a dish or kettle had been broken to pieces. + +“Please, then,” said Alice, “how am I to get in?” + +“There might be some sense in your knocking,” the Footman went on without attending to her, “if we had the door between us. For instance, if you were inside, you might knock, and I could let you out, you know.” He was looking up into the sky all the time he was speaking, and this Alice thought decidedly uncivil. “But perhaps he can’t help it,” she said to herself; “his eyes are so very nearly at the top of his head. But at any rate he might answer questions.—How am I to get in?” she repeated, aloud. + +“I shall sit here,” the Footman remarked, “till tomorrow—” + +At this moment the door of the house opened, and a large plate came skimming out, straight at the Footman’s head: it just grazed his nose, and broke to pieces against one of the trees behind him. + +“—or next day, maybe,” the Footman continued in the same tone, exactly as if nothing had happened. + +“How am I to get in?” asked Alice again, in a louder tone. + +“Are you to get in at all?” said the Footman. “That’s the first question, you know.” + +It was, no doubt: only Alice did not like to be told so. “It’s really dreadful,” she muttered to herself, “the way all the creatures argue. It’s enough to drive one crazy!” + +The Footman seemed to think this a good opportunity for repeating his remark, with variations. “I shall sit here,” he said, “on and off, for days and days.” + +“But what am I to do?” said Alice. + +“Anything you like,” said the Footman, and began whistling. + +“Oh, there’s no use in talking to him,” said Alice desperately: “he’s perfectly idiotic!” And she opened the door and went in. + +The door led right into a large kitchen, which was full of smoke from one end to the other: the Duchess was sitting on a three-legged stool in the middle, nursing a baby; the cook was leaning over the fire, stirring a large cauldron which seemed to be full of soup. + +“There’s certainly too much pepper in that soup!” Alice said to herself, as well as she could for sneezing. + +There was certainly too much of it in the air. Even the Duchess sneezed occasionally; and as for the baby, it was sneezing and howling alternately without a moment’s pause. The only things in the kitchen that did not sneeze, were the cook, and a large cat which was sitting on the hearth and grinning from ear to ear. + +“Please would you tell me,” said Alice, a little timidly, for she was not quite sure whether it was good manners for her to speak first, “why your cat grins like that?” + +“It’s a Cheshire cat,” said the Duchess, “and that’s why. Pig!” + +She said the last word with such sudden violence that Alice quite jumped; but she saw in another moment that it was addressed to the baby, and not to her, so she took courage, and went on again:— + +“I didn’t know that Cheshire cats always grinned; in fact, I didn’t know that cats could grin.” + +“They all can,” said the Duchess; “and most of ’em do.” + +“I don’t know of any that do,” Alice said very politely, feeling quite pleased to have got into a conversation. + +“You don’t know much,” said the Duchess; “and that’s a fact.” + +Alice did not at all like the tone of this remark, and thought it would be as well to introduce some other subject of conversation. While she was trying to fix on one, the cook took the cauldron of soup off the fire, and at once set to work throwing everything within her reach at the Duchess and the baby—the fire-irons came first; then followed a shower of saucepans, plates, and dishes. The Duchess took no notice of them even when they hit her; and the baby was howling so much already, that it was quite impossible to say whether the blows hurt it or not. + +“Oh, please mind what you’re doing!” cried Alice, jumping up and down in an agony of terror. “Oh, there goes his precious nose!” as an unusually large saucepan flew close by it, and very nearly carried it off. + +“If everybody minded their own business,” the Duchess said in a hoarse growl, “the world would go round a deal faster than it does.” + +“Which would not be an advantage,” said Alice, who felt very glad to get an opportunity of showing off a little of her knowledge. “Just think of what work it would make with the day and night! You see the earth takes twenty-four hours to turn round on its axis—” + +“Talking of axes,” said the Duchess, “chop off her head!” + +Alice glanced rather anxiously at the cook, to see if she meant to take the hint; but the cook was busily stirring the soup, and seemed not to be listening, so she went on again: “Twenty-four hours, I think; or is it twelve? I—” + +“Oh, don’t bother me,” said the Duchess; “I never could abide figures!” And with that she began nursing her child again, singing a sort of lullaby to it as she did so, and giving it a violent shake at the end of every line: + +“Speak roughly to your little boy, + And beat him when he sneezes: +He only does it to annoy, + Because he knows it teases.” + +CHORUS. +(In which the cook and the baby joined): + +“Wow! wow! wow!” + +While the Duchess sang the second verse of the song, she kept tossing the baby violently up and down, and the poor little thing howled so, that Alice could hardly hear the words:— + +“I speak severely to my boy, + I beat him when he sneezes; +For he can thoroughly enjoy + The pepper when he pleases!” + +CHORUS. + +“Wow! wow! wow!” + +“Here! you may nurse it a bit, if you like!” the Duchess said to Alice, flinging the baby at her as she spoke. “I must go and get ready to play croquet with the Queen,” and she hurried out of the room. The cook threw a frying-pan after her as she went out, but it just missed her. + +Alice caught the baby with some difficulty, as it was a queer-shaped little creature, and held out its arms and legs in all directions, “just like a star-fish,” thought Alice. The poor little thing was snorting like a steam-engine when she caught it, and kept doubling itself up and straightening itself out again, so that altogether, for the first minute or two, it was as much as she could do to hold it. + +As soon as she had made out the proper way of nursing it, (which was to twist it up into a sort of knot, and then keep tight hold of its right ear and left foot, so as to prevent its undoing itself,) she carried it out into the open air. “If I don’t take this child away with me,” thought Alice, “they’re sure to kill it in a day or two: wouldn’t it be murder to leave it behind?” She said the last words out loud, and the little thing grunted in reply (it had left off sneezing by this time). “Don’t grunt,” said Alice; “that’s not at all a proper way of expressing yourself.” + +The baby grunted again, and Alice looked very anxiously into its face to see what was the matter with it. There could be no doubt that it had a very turn-up nose, much more like a snout than a real nose; also its eyes were getting extremely small for a baby: altogether Alice did not like the look of the thing at all. “But perhaps it was only sobbing,” she thought, and looked into its eyes again, to see if there were any tears. + +No, there were no tears. “If you’re going to turn into a pig, my dear,” said Alice, seriously, “I’ll have nothing more to do with you. Mind now!” The poor little thing sobbed again (or grunted, it was impossible to say which), and they went on for some while in silence. + +Alice was just beginning to think to herself, “Now, what am I to do with this creature when I get it home?” when it grunted again, so violently, that she looked down into its face in some alarm. This time there could be no mistake about it: it was neither more nor less than a pig, and she felt that it would be quite absurd for her to carry it further. + +So she set the little creature down, and felt quite relieved to see it trot away quietly into the wood. “If it had grown up,” she said to herself, “it would have made a dreadfully ugly child: but it makes rather a handsome pig, I think.” And she began thinking over other children she knew, who might do very well as pigs, and was just saying to herself, “if one only knew the right way to change them—” when she was a little startled by seeing the Cheshire Cat sitting on a bough of a tree a few yards off. + +The Cat only grinned when it saw Alice. It looked good-natured, she thought: still it had very long claws and a great many teeth, so she felt that it ought to be treated with respect. + +“Cheshire Puss,” she began, rather timidly, as she did not at all know whether it would like the name: however, it only grinned a little wider. “Come, it’s pleased so far,” thought Alice, and she went on. “Would you tell me, please, which way I ought to go from here?” + +“That depends a good deal on where you want to get to,” said the Cat. + +“I don’t much care where—” said Alice. + +“Then it doesn’t matter which way you go,” said the Cat. + +“—so long as I get somewhere,” Alice added as an explanation. + +“Oh, you’re sure to do that,” said the Cat, “if you only walk long enough.” + +Alice felt that this could not be denied, so she tried another question. “What sort of people live about here?” + +“In that direction,” the Cat said, waving its right paw round, “lives a Hatter: and in that direction,” waving the other paw, “lives a March Hare. Visit either you like: they’re both mad.” + +“But I don’t want to go among mad people,” Alice remarked. + +“Oh, you can’t help that,” said the Cat: “we’re all mad here. I’m mad. You’re mad.” + +“How do you know I’m mad?” said Alice. + +“You must be,” said the Cat, “or you wouldn’t have come here.” + +Alice didn’t think that proved it at all; however, she went on “And how do you know that you’re mad?” + +“To begin with,” said the Cat, “a dog’s not mad. You grant that?” + +“I suppose so,” said Alice. + +“Well, then,” the Cat went on, “you see, a dog growls when it’s angry, and wags its tail when it’s pleased. Now I growl when I’m pleased, and wag my tail when I’m angry. Therefore I’m mad.” + +“I call it purring, not growling,” said Alice. + +“Call it what you like,” said the Cat. “Do you play croquet with the Queen to-day?” + +“I should like it very much,” said Alice, “but I haven’t been invited yet.” + +“You’ll see me there,” said the Cat, and vanished. + +Alice was not much surprised at this, she was getting so used to queer things happening. While she was looking at the place where it had been, it suddenly appeared again. + +“By-the-bye, what became of the baby?” said the Cat. “I’d nearly forgotten to ask.” + +“It turned into a pig,” Alice quietly said, just as if it had come back in a natural way. + +“I thought it would,” said the Cat, and vanished again. + +Alice waited a little, half expecting to see it again, but it did not appear, and after a minute or two she walked on in the direction in which the March Hare was said to live. “I’ve seen hatters before,” she said to herself; “the March Hare will be much the most interesting, and perhaps as this is May it won’t be raving mad—at least not so mad as it was in March.” As she said this, she looked up, and there was the Cat again, sitting on a branch of a tree. + +“Did you say pig, or fig?” said the Cat. + +“I said pig,” replied Alice; “and I wish you wouldn’t keep appearing and vanishing so suddenly: you make one quite giddy.” + +“All right,” said the Cat; and this time it vanished quite slowly, beginning with the end of the tail, and ending with the grin, which remained some time after the rest of it had gone. + +“Well! I’ve often seen a cat without a grin,” thought Alice; “but a grin without a cat! It’s the most curious thing I ever saw in my life!” + +She had not gone much farther before she came in sight of the house of the March Hare: she thought it must be the right house, because the chimneys were shaped like ears and the roof was thatched with fur. It was so large a house, that she did not like to go nearer till she had nibbled some more of the lefthand bit of mushroom, and raised herself to about two feet high: even then she walked up towards it rather timidly, saying to herself “Suppose it should be raving mad after all! I almost wish I’d gone to see the Hatter instead!” + +CHAPTER VII. +A Mad Tea-Party +There was a table set out under a tree in front of the house, and the March Hare and the Hatter were having tea at it: a Dormouse was sitting between them, fast asleep, and the other two were using it as a cushion, resting their elbows on it, and talking over its head. “Very uncomfortable for the Dormouse,” thought Alice; “only, as it’s asleep, I suppose it doesn’t mind.” + +The table was a large one, but the three were all crowded together at one corner of it: “No room! No room!” they cried out when they saw Alice coming. “There’s plenty of room!” said Alice indignantly, and she sat down in a large arm-chair at one end of the table. + +“Have some wine,” the March Hare said in an encouraging tone. + +Alice looked all round the table, but there was nothing on it but tea. “I don’t see any wine,” she remarked. + +“There isn’t any,” said the March Hare. + +“Then it wasn’t very civil of you to offer it,” said Alice angrily. + +“It wasn’t very civil of you to sit down without being invited,” said the March Hare. + +“I didn’t know it was your table,” said Alice; “it’s laid for a great many more than three.” + +“Your hair wants cutting,” said the Hatter. He had been looking at Alice for some time with great curiosity, and this was his first speech. + +“You should learn not to make personal remarks,” Alice said with some severity; “it’s very rude.” + +The Hatter opened his eyes very wide on hearing this; but all he said was, “Why is a raven like a writing-desk?” + +“Come, we shall have some fun now!” thought Alice. “I’m glad they’ve begun asking riddles.—I believe I can guess that,” she added aloud. + +“Do you mean that you think you can find out the answer to it?” said the March Hare. + +“Exactly so,” said Alice. + +“Then you should say what you mean,” the March Hare went on. + +“I do,” Alice hastily replied; “at least—at least I mean what I say—that’s the same thing, you know.” + +“Not the same thing a bit!” said the Hatter. “You might just as well say that ‘I see what I eat’ is the same thing as ‘I eat what I see’!” + +“You might just as well say,” added the March Hare, “that ‘I like what I get’ is the same thing as ‘I get what I like’!” + +“You might just as well say,” added the Dormouse, who seemed to be talking in his sleep, “that ‘I breathe when I sleep’ is the same thing as ‘I sleep when I breathe’!” + +“It is the same thing with you,” said the Hatter, and here the conversation dropped, and the party sat silent for a minute, while Alice thought over all she could remember about ravens and writing-desks, which wasn’t much. + +The Hatter was the first to break the silence. “What day of the month is it?” he said, turning to Alice: he had taken his watch out of his pocket, and was looking at it uneasily, shaking it every now and then, and holding it to his ear. + +Alice considered a little, and then said “The fourth.” + +“Two days wrong!” sighed the Hatter. “I told you butter wouldn’t suit the works!” he added looking angrily at the March Hare. + +“It was the best butter,” the March Hare meekly replied. + +“Yes, but some crumbs must have got in as well,” the Hatter grumbled: “you shouldn’t have put it in with the bread-knife.” + +The March Hare took the watch and looked at it gloomily: then he dipped it into his cup of tea, and looked at it again: but he could think of nothing better to say than his first remark, “It was the best butter, you know.” + +Alice had been looking over his shoulder with some curiosity. “What a funny watch!” she remarked. “It tells the day of the month, and doesn’t tell what o’clock it is!” + +“Why should it?” muttered the Hatter. “Does your watch tell you what year it is?” + +“Of course not,” Alice replied very readily: “but that’s because it stays the same year for such a long time together.” + +“Which is just the case with mine,” said the Hatter. + +Alice felt dreadfully puzzled. The Hatter’s remark seemed to have no sort of meaning in it, and yet it was certainly English. “I don’t quite understand you,” she said, as politely as she could. + +“The Dormouse is asleep again,” said the Hatter, and he poured a little hot tea upon its nose. + +The Dormouse shook its head impatiently, and said, without opening its eyes, “Of course, of course; just what I was going to remark myself.” + +“Have you guessed the riddle yet?” the Hatter said, turning to Alice again. + +“No, I give it up,” Alice replied: “what’s the answer?” + +“I haven’t the slightest idea,” said the Hatter. + +“Nor I,” said the March Hare. + +Alice sighed wearily. “I think you might do something better with the time,” she said, “than waste it in asking riddles that have no answers.” + +“If you knew Time as well as I do,” said the Hatter, “you wouldn’t talk about wasting it. It’s him.” + +“I don’t know what you mean,” said Alice. + +“Of course you don’t!” the Hatter said, tossing his head contemptuously. “I dare say you never even spoke to Time!” + +“Perhaps not,” Alice cautiously replied: “but I know I have to beat time when I learn music.” + +“Ah! that accounts for it,” said the Hatter. “He won’t stand beating. Now, if you only kept on good terms with him, he’d do almost anything you liked with the clock. For instance, suppose it were nine o’clock in the morning, just time to begin lessons: you’d only have to whisper a hint to Time, and round goes the clock in a twinkling! Half-past one, time for dinner!” + +(“I only wish it was,” the March Hare said to itself in a whisper.) + +“That would be grand, certainly,” said Alice thoughtfully: “but then—I shouldn’t be hungry for it, you know.” + +“Not at first, perhaps,” said the Hatter: “but you could keep it to half-past one as long as you liked.” + +“Is that the way you manage?” Alice asked. + +The Hatter shook his head mournfully. “Not I!” he replied. “We quarrelled last March—just before he went mad, you know—” (pointing with his tea spoon at the March Hare,) “—it was at the great concert given by the Queen of Hearts, and I had to sing + +‘Twinkle, twinkle, little bat! +How I wonder what you’re at!’ + +You know the song, perhaps?” + +“I’ve heard something like it,” said Alice. + +“It goes on, you know,” the Hatter continued, “in this way:— + +‘Up above the world you fly, +Like a tea-tray in the sky. + Twinkle, twinkle—’” + +Here the Dormouse shook itself, and began singing in its sleep “Twinkle, twinkle, twinkle, twinkle—” and went on so long that they had to pinch it to make it stop. + +“Well, I’d hardly finished the first verse,” said the Hatter, “when the Queen jumped up and bawled out, ‘He’s murdering the time! Off with his head!’” + +“How dreadfully savage!” exclaimed Alice. + +“And ever since that,” the Hatter went on in a mournful tone, “he won’t do a thing I ask! It’s always six o’clock now.” + +A bright idea came into Alice’s head. “Is that the reason so many tea-things are put out here?” she asked. + +“Yes, that’s it,” said the Hatter with a sigh: “it’s always tea-time, and we’ve no time to wash the things between whiles.” + +“Then you keep moving round, I suppose?” said Alice. + +“Exactly so,” said the Hatter: “as the things get used up.” + +“But what happens when you come to the beginning again?” Alice ventured to ask. + +“Suppose we change the subject,” the March Hare interrupted, yawning. “I’m getting tired of this. I vote the young lady tells us a story.” + +“I’m afraid I don’t know one,” said Alice, rather alarmed at the proposal. + +“Then the Dormouse shall!” they both cried. “Wake up, Dormouse!” And they pinched it on both sides at once. + +The Dormouse slowly opened his eyes. “I wasn’t asleep,” he said in a hoarse, feeble voice: “I heard every word you fellows were saying.” + +“Tell us a story!” said the March Hare. + +“Yes, please do!” pleaded Alice. + +“And be quick about it,” added the Hatter, “or you’ll be asleep again before it’s done.” + +“Once upon a time there were three little sisters,” the Dormouse began in a great hurry; “and their names were Elsie, Lacie, and Tillie; and they lived at the bottom of a well—” + +“What did they live on?” said Alice, who always took a great interest in questions of eating and drinking. + +“They lived on treacle,” said the Dormouse, after thinking a minute or two. + +“They couldn’t have done that, you know,” Alice gently remarked; “they’d have been ill.” + +“So they were,” said the Dormouse; “very ill.” + +Alice tried to fancy to herself what such an extraordinary ways of living would be like, but it puzzled her too much, so she went on: “But why did they live at the bottom of a well?” + +“Take some more tea,” the March Hare said to Alice, very earnestly. + +“I’ve had nothing yet,” Alice replied in an offended tone, “so I can’t take more.” + +“You mean you can’t take less,” said the Hatter: “it’s very easy to take more than nothing.” + +“Nobody asked your opinion,” said Alice. + +“Who’s making personal remarks now?” the Hatter asked triumphantly. + +Alice did not quite know what to say to this: so she helped herself to some tea and bread-and-butter, and then turned to the Dormouse, and repeated her question. “Why did they live at the bottom of a well?” + +The Dormouse again took a minute or two to think about it, and then said, “It was a treacle-well.” + +“There’s no such thing!” Alice was beginning very angrily, but the Hatter and the March Hare went “Sh! sh!” and the Dormouse sulkily remarked, “If you can’t be civil, you’d better finish the story for yourself.” + +“No, please go on!” Alice said very humbly; “I won’t interrupt again. I dare say there may be one.” + +“One, indeed!” said the Dormouse indignantly. However, he consented to go on. “And so these three little sisters—they were learning to draw, you know—” + +“What did they draw?” said Alice, quite forgetting her promise. + +“Treacle,” said the Dormouse, without considering at all this time. + +“I want a clean cup,” interrupted the Hatter: “let’s all move one place on.” + +He moved on as he spoke, and the Dormouse followed him: the March Hare moved into the Dormouse’s place, and Alice rather unwillingly took the place of the March Hare. The Hatter was the only one who got any advantage from the change: and Alice was a good deal worse off than before, as the March Hare had just upset the milk-jug into his plate. + +Alice did not wish to offend the Dormouse again, so she began very cautiously: “But I don’t understand. Where did they draw the treacle from?” + +“You can draw water out of a water-well,” said the Hatter; “so I should think you could draw treacle out of a treacle-well—eh, stupid?” + +“But they were in the well,” Alice said to the Dormouse, not choosing to notice this last remark. + +“Of course they were,” said the Dormouse; “—well in.” + +This answer so confused poor Alice, that she let the Dormouse go on for some time without interrupting it. + +“They were learning to draw,” the Dormouse went on, yawning and rubbing its eyes, for it was getting very sleepy; “and they drew all manner of things—everything that begins with an M—” + +“Why with an M?” said Alice. + +“Why not?” said the March Hare. + +Alice was silent. + +The Dormouse had closed its eyes by this time, and was going off into a doze; but, on being pinched by the Hatter, it woke up again with a little shriek, and went on: “—that begins with an M, such as mouse-traps, and the moon, and memory, and muchness—you know you say things are “much of a muchness”—did you ever see such a thing as a drawing of a muchness?” + +“Really, now you ask me,” said Alice, very much confused, “I don’t think—” + +“Then you shouldn’t talk,” said the Hatter. + +This piece of rudeness was more than Alice could bear: she got up in great disgust, and walked off; the Dormouse fell asleep instantly, and neither of the others took the least notice of her going, though she looked back once or twice, half hoping that they would call after her: the last time she saw them, they were trying to put the Dormouse into the teapot. + +“At any rate I’ll never go there again!” said Alice as she picked her way through the wood. “It’s the stupidest tea-party I ever was at in all my life!” + +Just as she said this, she noticed that one of the trees had a door leading right into it. “That’s very curious!” she thought. “But everything’s curious today. I think I may as well go in at once.” And in she went. + +Once more she found herself in the long hall, and close to the little glass table. “Now, I’ll manage better this time,” she said to herself, and began by taking the little golden key, and unlocking the door that led into the garden. Then she went to work nibbling at the mushroom (she had kept a piece of it in her pocket) till she was about a foot high: then she walked down the little passage: and then—she found herself at last in the beautiful garden, among the bright flower-beds and the cool fountains. + +CHAPTER VIII. +The Queen’s Croquet-Ground +A large rose-tree stood near the entrance of the garden: the roses growing on it were white, but there were three gardeners at it, busily painting them red. Alice thought this a very curious thing, and she went nearer to watch them, and just as she came up to them she heard one of them say, “Look out now, Five! Don’t go splashing paint over me like that!” + +“I couldn’t help it,” said Five, in a sulky tone; “Seven jogged my elbow.” + +On which Seven looked up and said, “That’s right, Five! Always lay the blame on others!” + +“You’d better not talk!” said Five. “I heard the Queen say only yesterday you deserved to be beheaded!” + +“What for?” said the one who had spoken first. + +“That’s none of your business, Two!” said Seven. + +“Yes, it is his business!” said Five, “and I’ll tell him—it was for bringing the cook tulip-roots instead of onions.” + +Seven flung down his brush, and had just begun “Well, of all the unjust things—” when his eye chanced to fall upon Alice, as she stood watching them, and he checked himself suddenly: the others looked round also, and all of them bowed low. + +“Would you tell me,” said Alice, a little timidly, “why you are painting those roses?” + +Five and Seven said nothing, but looked at Two. Two began in a low voice, “Why the fact is, you see, Miss, this here ought to have been a red rose-tree, and we put a white one in by mistake; and if the Queen was to find it out, we should all have our heads cut off, you know. So you see, Miss, we’re doing our best, afore she comes, to—” At this moment Five, who had been anxiously looking across the garden, called out “The Queen! The Queen!” and the three gardeners instantly threw themselves flat upon their faces. There was a sound of many footsteps, and Alice looked round, eager to see the Queen. + +First came ten soldiers carrying clubs; these were all shaped like the three gardeners, oblong and flat, with their hands and feet at the corners: next the ten courtiers; these were ornamented all over with diamonds, and walked two and two, as the soldiers did. After these came the royal children; there were ten of them, and the little dears came jumping merrily along hand in hand, in couples: they were all ornamented with hearts. Next came the guests, mostly Kings and Queens, and among them Alice recognised the White Rabbit: it was talking in a hurried nervous manner, smiling at everything that was said, and went by without noticing her. Then followed the Knave of Hearts, carrying the King’s crown on a crimson velvet cushion; and, last of all this grand procession, came THE KING AND QUEEN OF HEARTS. + +Alice was rather doubtful whether she ought not to lie down on her face like the three gardeners, but she could not remember ever having heard of such a rule at processions; “and besides, what would be the use of a procession,” thought she, “if people had all to lie down upon their faces, so that they couldn’t see it?” So she stood still where she was, and waited. + +When the procession came opposite to Alice, they all stopped and looked at her, and the Queen said severely “Who is this?” She said it to the Knave of Hearts, who only bowed and smiled in reply. + +“Idiot!” said the Queen, tossing her head impatiently; and, turning to Alice, she went on, “What’s your name, child?” + +“My name is Alice, so please your Majesty,” said Alice very politely; but she added, to herself, “Why, they’re only a pack of cards, after all. I needn’t be afraid of them!” + +“And who are these?” said the Queen, pointing to the three gardeners who were lying round the rose-tree; for, you see, as they were lying on their faces, and the pattern on their backs was the same as the rest of the pack, she could not tell whether they were gardeners, or soldiers, or courtiers, or three of her own children. + +“How should I know?” said Alice, surprised at her own courage. “It’s no business of mine.” + +The Queen turned crimson with fury, and, after glaring at her for a moment like a wild beast, screamed “Off with her head! Off—” + +“Nonsense!” said Alice, very loudly and decidedly, and the Queen was silent. + +The King laid his hand upon her arm, and timidly said “Consider, my dear: she is only a child!” + +The Queen turned angrily away from him, and said to the Knave “Turn them over!” + +The Knave did so, very carefully, with one foot. + +“Get up!” said the Queen, in a shrill, loud voice, and the three gardeners instantly jumped up, and began bowing to the King, the Queen, the royal children, and everybody else. + +“Leave off that!” screamed the Queen. “You make me giddy.” And then, turning to the rose-tree, she went on, “What have you been doing here?” + +“May it please your Majesty,” said Two, in a very humble tone, going down on one knee as he spoke, “we were trying—” + +“I see!” said the Queen, who had meanwhile been examining the roses. “Off with their heads!” and the procession moved on, three of the soldiers remaining behind to execute the unfortunate gardeners, who ran to Alice for protection. + +“You shan’t be beheaded!” said Alice, and she put them into a large flower-pot that stood near. The three soldiers wandered about for a minute or two, looking for them, and then quietly marched off after the others. + +“Are their heads off?” shouted the Queen. + +“Their heads are gone, if it please your Majesty!” the soldiers shouted in reply. + +“That’s right!” shouted the Queen. “Can you play croquet?” + +The soldiers were silent, and looked at Alice, as the question was evidently meant for her. + +“Yes!” shouted Alice. + +“Come on, then!” roared the Queen, and Alice joined the procession, wondering very much what would happen next. + +“It’s—it’s a very fine day!” said a timid voice at her side. She was walking by the White Rabbit, who was peeping anxiously into her face. + +“Very,” said Alice: “—where’s the Duchess?” + +“Hush! Hush!” said the Rabbit in a low, hurried tone. He looked anxiously over his shoulder as he spoke, and then raised himself upon tiptoe, put his mouth close to her ear, and whispered “She’s under sentence of execution.” + +“What for?” said Alice. + +“Did you say ‘What a pity!’?” the Rabbit asked. + +“No, I didn’t,” said Alice: “I don’t think it’s at all a pity. I said ‘What for?’” + +“She boxed the Queen’s ears—” the Rabbit began. Alice gave a little scream of laughter. “Oh, hush!” the Rabbit whispered in a frightened tone. “The Queen will hear you! You see, she came rather late, and the Queen said—” + +“Get to your places!” shouted the Queen in a voice of thunder, and people began running about in all directions, tumbling up against each other; however, they got settled down in a minute or two, and the game began. Alice thought she had never seen such a curious croquet-ground in her life; it was all ridges and furrows; the balls were live hedgehogs, the mallets live flamingoes, and the soldiers had to double themselves up and to stand on their hands and feet, to make the arches. + +The chief difficulty Alice found at first was in managing her flamingo: she succeeded in getting its body tucked away, comfortably enough, under her arm, with its legs hanging down, but generally, just as she had got its neck nicely straightened out, and was going to give the hedgehog a blow with its head, it would twist itself round and look up in her face, with such a puzzled expression that she could not help bursting out laughing: and when she had got its head down, and was going to begin again, it was very provoking to find that the hedgehog had unrolled itself, and was in the act of crawling away: besides all this, there was generally a ridge or furrow in the way wherever she wanted to send the hedgehog to, and, as the doubled-up soldiers were always getting up and walking off to other parts of the ground, Alice soon came to the conclusion that it was a very difficult game indeed. + +The players all played at once without waiting for turns, quarrelling all the while, and fighting for the hedgehogs; and in a very short time the Queen was in a furious passion, and went stamping about, and shouting “Off with his head!” or “Off with her head!” about once in a minute. + +Alice began to feel very uneasy: to be sure, she had not as yet had any dispute with the Queen, but she knew that it might happen any minute, “and then,” thought she, “what would become of me? They’re dreadfully fond of beheading people here; the great wonder is, that there’s any one left alive!” + +She was looking about for some way of escape, and wondering whether she could get away without being seen, when she noticed a curious appearance in the air: it puzzled her very much at first, but, after watching it a minute or two, she made it out to be a grin, and she said to herself “It’s the Cheshire Cat: now I shall have somebody to talk to.” + +“How are you getting on?” said the Cat, as soon as there was mouth enough for it to speak with. + +Alice waited till the eyes appeared, and then nodded. “It’s no use speaking to it,” she thought, “till its ears have come, or at least one of them.” In another minute the whole head appeared, and then Alice put down her flamingo, and began an account of the game, feeling very glad she had someone to listen to her. The Cat seemed to think that there was enough of it now in sight, and no more of it appeared. + +“I don’t think they play at all fairly,” Alice began, in rather a complaining tone, “and they all quarrel so dreadfully one can’t hear oneself speak—and they don’t seem to have any rules in particular; at least, if there are, nobody attends to them—and you’ve no idea how confusing it is all the things being alive; for instance, there’s the arch I’ve got to go through next walking about at the other end of the ground—and I should have croqueted the Queen’s hedgehog just now, only it ran away when it saw mine coming!” + +“How do you like the Queen?” said the Cat in a low voice. + +“Not at all,” said Alice: “she’s so extremely—” Just then she noticed that the Queen was close behind her, listening: so she went on, “—likely to win, that it’s hardly worth while finishing the game.” + +The Queen smiled and passed on. + +“Who are you talking to?” said the King, going up to Alice, and looking at the Cat’s head with great curiosity. + +“It’s a friend of mine—a Cheshire Cat,” said Alice: “allow me to introduce it.” + +“I don’t like the look of it at all,” said the King: “however, it may kiss my hand if it likes.” + +“I’d rather not,” the Cat remarked. + +“Don’t be impertinent,” said the King, “and don’t look at me like that!” He got behind Alice as he spoke. + +“A cat may look at a king,” said Alice. “I’ve read that in some book, but I don’t remember where.” + +“Well, it must be removed,” said the King very decidedly, and he called the Queen, who was passing at the moment, “My dear! I wish you would have this cat removed!” + +The Queen had only one way of settling all difficulties, great or small. “Off with his head!” she said, without even looking round. + +“I’ll fetch the executioner myself,” said the King eagerly, and he hurried off. + +Alice thought she might as well go back, and see how the game was going on, as she heard the Queen’s voice in the distance, screaming with passion. She had already heard her sentence three of the players to be executed for having missed their turns, and she did not like the look of things at all, as the game was in such confusion that she never knew whether it was her turn or not. So she went in search of her hedgehog. + +The hedgehog was engaged in a fight with another hedgehog, which seemed to Alice an excellent opportunity for croqueting one of them with the other: the only difficulty was, that her flamingo was gone across to the other side of the garden, where Alice could see it trying in a helpless sort of way to fly up into a tree. + +By the time she had caught the flamingo and brought it back, the fight was over, and both the hedgehogs were out of sight: “but it doesn’t matter much,” thought Alice, “as all the arches are gone from this side of the ground.” So she tucked it away under her arm, that it might not escape again, and went back for a little more conversation with her friend. + +When she got back to the Cheshire Cat, she was surprised to find quite a large crowd collected round it: there was a dispute going on between the executioner, the King, and the Queen, who were all talking at once, while all the rest were quite silent, and looked very uncomfortable. + +The moment Alice appeared, she was appealed to by all three to settle the question, and they repeated their arguments to her, though, as they all spoke at once, she found it very hard indeed to make out exactly what they said. + +The executioner’s argument was, that you couldn’t cut off a head unless there was a body to cut it off from: that he had never had to do such a thing before, and he wasn’t going to begin at his time of life. + +The King’s argument was, that anything that had a head could be beheaded, and that you weren’t to talk nonsense. + +The Queen’s argument was, that if something wasn’t done about it in less than no time she’d have everybody executed, all round. (It was this last remark that had made the whole party look so grave and anxious.) + +Alice could think of nothing else to say but “It belongs to the Duchess: you’d better ask her about it.” + +“She’s in prison,” the Queen said to the executioner: “fetch her here.” And the executioner went off like an arrow. + +The Cat’s head began fading away the moment he was gone, and, by the time he had come back with the Duchess, it had entirely disappeared; so the King and the executioner ran wildly up and down looking for it, while the rest of the party went back to the game. + +CHAPTER IX. +The Mock Turtle’s Story +“You can’t think how glad I am to see you again, you dear old thing!” said the Duchess, as she tucked her arm affectionately into Alice’s, and they walked off together. + +Alice was very glad to find her in such a pleasant temper, and thought to herself that perhaps it was only the pepper that had made her so savage when they met in the kitchen. + +“When I’m a Duchess,” she said to herself, (not in a very hopeful tone though), “I won’t have any pepper in my kitchen at all. Soup does very well without—Maybe it’s always pepper that makes people hot-tempered,” she went on, very much pleased at having found out a new kind of rule, “and vinegar that makes them sour—and camomile that makes them bitter—and—and barley-sugar and such things that make children sweet-tempered. I only wish people knew that: then they wouldn’t be so stingy about it, you know—” + +She had quite forgotten the Duchess by this time, and was a little startled when she heard her voice close to her ear. “You’re thinking about something, my dear, and that makes you forget to talk. I can’t tell you just now what the moral of that is, but I shall remember it in a bit.” + +“Perhaps it hasn’t one,” Alice ventured to remark. + +“Tut, tut, child!” said the Duchess. “Everything’s got a moral, if only you can find it.” And she squeezed herself up closer to Alice’s side as she spoke. + +Alice did not much like keeping so close to her: first, because the Duchess was very ugly; and secondly, because she was exactly the right height to rest her chin upon Alice’s shoulder, and it was an uncomfortably sharp chin. However, she did not like to be rude, so she bore it as well as she could. + +“The game’s going on rather better now,” she said, by way of keeping up the conversation a little. + +“’Tis so,” said the Duchess: “and the moral of that is—‘Oh, ’tis love, ’tis love, that makes the world go round!’” + +“Somebody said,” Alice whispered, “that it’s done by everybody minding their own business!” + +“Ah, well! It means much the same thing,” said the Duchess, digging her sharp little chin into Alice’s shoulder as she added, “and the moral of that is—‘Take care of the sense, and the sounds will take care of themselves.’” + +“How fond she is of finding morals in things!” Alice thought to herself. + +“I dare say you’re wondering why I don’t put my arm round your waist,” the Duchess said after a pause: “the reason is, that I’m doubtful about the temper of your flamingo. Shall I try the experiment?” + +“He might bite,” Alice cautiously replied, not feeling at all anxious to have the experiment tried. + +“Very true,” said the Duchess: “flamingoes and mustard both bite. And the moral of that is—‘Birds of a feather flock together.’” + +“Only mustard isn’t a bird,” Alice remarked. + +“Right, as usual,” said the Duchess: “what a clear way you have of putting things!” + +“It’s a mineral, I think,” said Alice. + +“Of course it is,” said the Duchess, who seemed ready to agree to everything that Alice said; “there’s a large mustard-mine near here. And the moral of that is—‘The more there is of mine, the less there is of yours.’” + +“Oh, I know!” exclaimed Alice, who had not attended to this last remark, “it’s a vegetable. It doesn’t look like one, but it is.” + +“I quite agree with you,” said the Duchess; “and the moral of that is—‘Be what you would seem to be’—or if you’d like it put more simply—‘Never imagine yourself not to be otherwise than what it might appear to others that what you were or might have been was not otherwise than what you had been would have appeared to them to be otherwise.’” + +“I think I should understand that better,” Alice said very politely, “if I had it written down: but I can’t quite follow it as you say it.” + +“That’s nothing to what I could say if I chose,” the Duchess replied, in a pleased tone. + +“Pray don’t trouble yourself to say it any longer than that,” said Alice. + +“Oh, don’t talk about trouble!” said the Duchess. “I make you a present of everything I’ve said as yet.” + +“A cheap sort of present!” thought Alice. “I’m glad they don’t give birthday presents like that!” But she did not venture to say it out loud. + +“Thinking again?” the Duchess asked, with another dig of her sharp little chin. + +“I’ve a right to think,” said Alice sharply, for she was beginning to feel a little worried. + +“Just about as much right,” said the Duchess, “as pigs have to fly; and the m—” + +But here, to Alice’s great surprise, the Duchess’s voice died away, even in the middle of her favourite word ‘moral,’ and the arm that was linked into hers began to tremble. Alice looked up, and there stood the Queen in front of them, with her arms folded, frowning like a thunderstorm. + +“A fine day, your Majesty!” the Duchess began in a low, weak voice. + +“Now, I give you fair warning,” shouted the Queen, stamping on the ground as she spoke; “either you or your head must be off, and that in about half no time! Take your choice!” + +The Duchess took her choice, and was gone in a moment. + +“Let’s go on with the game,” the Queen said to Alice; and Alice was too much frightened to say a word, but slowly followed her back to the croquet-ground. + +The other guests had taken advantage of the Queen’s absence, and were resting in the shade: however, the moment they saw her, they hurried back to the game, the Queen merely remarking that a moment’s delay would cost them their lives. + +All the time they were playing the Queen never left off quarrelling with the other players, and shouting “Off with his head!” or “Off with her head!” Those whom she sentenced were taken into custody by the soldiers, who of course had to leave off being arches to do this, so that by the end of half an hour or so there were no arches left, and all the players, except the King, the Queen, and Alice, were in custody and under sentence of execution. + +Then the Queen left off, quite out of breath, and said to Alice, “Have you seen the Mock Turtle yet?” + +“No,” said Alice. “I don’t even know what a Mock Turtle is.” + +“It’s the thing Mock Turtle Soup is made from,” said the Queen. + +“I never saw one, or heard of one,” said Alice. + +“Come on, then,” said the Queen, “and he shall tell you his history,” + +As they walked off together, Alice heard the King say in a low voice, to the company generally, “You are all pardoned.” “Come, that’s a good thing!” she said to herself, for she had felt quite unhappy at the number of executions the Queen had ordered. + +They very soon came upon a Gryphon, lying fast asleep in the sun. (If you don’t know what a Gryphon is, look at the picture.) “Up, lazy thing!” said the Queen, “and take this young lady to see the Mock Turtle, and to hear his history. I must go back and see after some executions I have ordered;” and she walked off, leaving Alice alone with the Gryphon. Alice did not quite like the look of the creature, but on the whole she thought it would be quite as safe to stay with it as to go after that savage Queen: so she waited. + +The Gryphon sat up and rubbed its eyes: then it watched the Queen till she was out of sight: then it chuckled. “What fun!” said the Gryphon, half to itself, half to Alice. + +“What is the fun?” said Alice. + +“Why, she,” said the Gryphon. “It’s all her fancy, that: they never executes nobody, you know. Come on!” + +“Everybody says ‘come on!’ here,” thought Alice, as she went slowly after it: “I never was so ordered about in all my life, never!” + +They had not gone far before they saw the Mock Turtle in the distance, sitting sad and lonely on a little ledge of rock, and, as they came nearer, Alice could hear him sighing as if his heart would break. She pitied him deeply. “What is his sorrow?” she asked the Gryphon, and the Gryphon answered, very nearly in the same words as before, “It’s all his fancy, that: he hasn’t got no sorrow, you know. Come on!” + +So they went up to the Mock Turtle, who looked at them with large eyes full of tears, but said nothing. + +“This here young lady,” said the Gryphon, “she wants for to know your history, she do.” + +“I’ll tell it her,” said the Mock Turtle in a deep, hollow tone: “sit down, both of you, and don’t speak a word till I’ve finished.” + +So they sat down, and nobody spoke for some minutes. Alice thought to herself, “I don’t see how he can ever finish, if he doesn’t begin.” But she waited patiently. + +“Once,” said the Mock Turtle at last, with a deep sigh, “I was a real Turtle.” + +These words were followed by a very long silence, broken only by an occasional exclamation of “Hjckrrh!” from the Gryphon, and the constant heavy sobbing of the Mock Turtle. Alice was very nearly getting up and saying, “Thank you, sir, for your interesting story,” but she could not help thinking there must be more to come, so she sat still and said nothing. + +“When we were little,” the Mock Turtle went on at last, more calmly, though still sobbing a little now and then, “we went to school in the sea. The master was an old Turtle—we used to call him Tortoise—” + +“Why did you call him Tortoise, if he wasn’t one?” Alice asked. + +“We called him Tortoise because he taught us,” said the Mock Turtle angrily: “really you are very dull!” + +“You ought to be ashamed of yourself for asking such a simple question,” added the Gryphon; and then they both sat silent and looked at poor Alice, who felt ready to sink into the earth. At last the Gryphon said to the Mock Turtle, “Drive on, old fellow! Don’t be all day about it!” and he went on in these words: + +“Yes, we went to school in the sea, though you mayn’t believe it—” + +“I never said I didn’t!” interrupted Alice. + +“You did,” said the Mock Turtle. + +“Hold your tongue!” added the Gryphon, before Alice could speak again. The Mock Turtle went on. + +“We had the best of educations—in fact, we went to school every day—” + +“I’ve been to a day-school, too,” said Alice; “you needn’t be so proud as all that.” + +“With extras?” asked the Mock Turtle a little anxiously. + +“Yes,” said Alice, “we learned French and music.” + +“And washing?” said the Mock Turtle. + +“Certainly not!” said Alice indignantly. + +“Ah! then yours wasn’t a really good school,” said the Mock Turtle in a tone of great relief. “Now at ours they had at the end of the bill, ‘French, music, and washing—extra.’” + +“You couldn’t have wanted it much,” said Alice; “living at the bottom of the sea.” + +“I couldn’t afford to learn it.” said the Mock Turtle with a sigh. “I only took the regular course.” + +“What was that?” inquired Alice. + +“Reeling and Writhing, of course, to begin with,” the Mock Turtle replied; “and then the different branches of Arithmetic—Ambition, Distraction, Uglification, and Derision.” + +“I never heard of ‘Uglification,’” Alice ventured to say. “What is it?” + +The Gryphon lifted up both its paws in surprise. “What! Never heard of uglifying!” it exclaimed. “You know what to beautify is, I suppose?” + +“Yes,” said Alice doubtfully: “it means—to—make—anything—prettier.” + +“Well, then,” the Gryphon went on, “if you don’t know what to uglify is, you are a simpleton.” + +Alice did not feel encouraged to ask any more questions about it, so she turned to the Mock Turtle, and said “What else had you to learn?” + +“Well, there was Mystery,” the Mock Turtle replied, counting off the subjects on his flappers, “—Mystery, ancient and modern, with Seaography: then Drawling—the Drawling-master was an old conger-eel, that used to come once a week: he taught us Drawling, Stretching, and Fainting in Coils.” + +“What was that like?” said Alice. + +“Well, I can’t show it you myself,” the Mock Turtle said: “I’m too stiff. And the Gryphon never learnt it.” + +“Hadn’t time,” said the Gryphon: “I went to the Classics master, though. He was an old crab, he was.” + +“I never went to him,” the Mock Turtle said with a sigh: “he taught Laughing and Grief, they used to say.” + +“So he did, so he did,” said the Gryphon, sighing in his turn; and both creatures hid their faces in their paws. + +“And how many hours a day did you do lessons?” said Alice, in a hurry to change the subject. + +“Ten hours the first day,” said the Mock Turtle: “nine the next, and so on.” + +“What a curious plan!” exclaimed Alice. + +“That’s the reason they’re called lessons,” the Gryphon remarked: “because they lessen from day to day.” + +This was quite a new idea to Alice, and she thought it over a little before she made her next remark. “Then the eleventh day must have been a holiday?” + +“Of course it was,” said the Mock Turtle. + +“And how did you manage on the twelfth?” Alice went on eagerly. + +“That’s enough about lessons,” the Gryphon interrupted in a very decided tone: “tell her something about the games now.” + +CHAPTER X. +The Lobster Quadrille +The Mock Turtle sighed deeply, and drew the back of one flapper across his eyes. He looked at Alice, and tried to speak, but for a minute or two sobs choked his voice. “Same as if he had a bone in his throat,” said the Gryphon: and it set to work shaking him and punching him in the back. At last the Mock Turtle recovered his voice, and, with tears running down his cheeks, he went on again:— + +“You may not have lived much under the sea—” (“I haven’t,” said Alice)—“and perhaps you were never even introduced to a lobster—” (Alice began to say “I once tasted—” but checked herself hastily, and said “No, never”) “—so you can have no idea what a delightful thing a Lobster Quadrille is!” + +“No, indeed,” said Alice. “What sort of a dance is it?” + +“Why,” said the Gryphon, “you first form into a line along the sea-shore—” + +“Two lines!” cried the Mock Turtle. “Seals, turtles, salmon, and so on; then, when you’ve cleared all the jelly-fish out of the way—” + +“That generally takes some time,” interrupted the Gryphon. + +“—you advance twice—” + +“Each with a lobster as a partner!” cried the Gryphon. + +“Of course,” the Mock Turtle said: “advance twice, set to partners—” + +“—change lobsters, and retire in same order,” continued the Gryphon. + +“Then, you know,” the Mock Turtle went on, “you throw the—” + +“The lobsters!” shouted the Gryphon, with a bound into the air. + +“—as far out to sea as you can—” + +“Swim after them!” screamed the Gryphon. + +“Turn a somersault in the sea!” cried the Mock Turtle, capering wildly about. + +“Change lobsters again!” yelled the Gryphon at the top of its voice. + +“Back to land again, and that’s all the first figure,” said the Mock Turtle, suddenly dropping his voice; and the two creatures, who had been jumping about like mad things all this time, sat down again very sadly and quietly, and looked at Alice. + +“It must be a very pretty dance,” said Alice timidly. + +“Would you like to see a little of it?” said the Mock Turtle. + +“Very much indeed,” said Alice. + +“Come, let’s try the first figure!” said the Mock Turtle to the Gryphon. “We can do without lobsters, you know. Which shall sing?” + +“Oh, you sing,” said the Gryphon. “I’ve forgotten the words.” + +So they began solemnly dancing round and round Alice, every now and then treading on her toes when they passed too close, and waving their forepaws to mark the time, while the Mock Turtle sang this, very slowly and sadly:— + +“Will you walk a little faster?” said a whiting to a snail. +“There’s a porpoise close behind us, and he’s treading on my tail. +See how eagerly the lobsters and the turtles all advance! +They are waiting on the shingle—will you come and join the dance? +Will you, won’t you, will you, won’t you, will you join the dance? +Will you, won’t you, will you, won’t you, won’t you join the dance? + +“You can really have no notion how delightful it will be +When they take us up and throw us, with the lobsters, out to sea!” +But the snail replied “Too far, too far!” and gave a look askance— +Said he thanked the whiting kindly, but he would not join the dance. +Would not, could not, would not, could not, would not join the dance. +Would not, could not, would not, could not, could not join the dance. + +“What matters it how far we go?” his scaly friend replied. +“There is another shore, you know, upon the other side. +The further off from England the nearer is to France— +Then turn not pale, beloved snail, but come and join the dance. +Will you, won’t you, will you, won’t you, will you join the dance? +Will you, won’t you, will you, won’t you, won’t you join the dance?” + +“Thank you, it’s a very interesting dance to watch,” said Alice, feeling very glad that it was over at last: “and I do so like that curious song about the whiting!” + +“Oh, as to the whiting,” said the Mock Turtle, “they—you’ve seen them, of course?” + +“Yes,” said Alice, “I’ve often seen them at dinn—” she checked herself hastily. + +“I don’t know where Dinn may be,” said the Mock Turtle, “but if you’ve seen them so often, of course you know what they’re like.” + +“I believe so,” Alice replied thoughtfully. “They have their tails in their mouths—and they’re all over crumbs.” + +“You’re wrong about the crumbs,” said the Mock Turtle: “crumbs would all wash off in the sea. But they have their tails in their mouths; and the reason is—” here the Mock Turtle yawned and shut his eyes.—“Tell her about the reason and all that,” he said to the Gryphon. + +“The reason is,” said the Gryphon, “that they would go with the lobsters to the dance. So they got thrown out to sea. So they had to fall a long way. So they got their tails fast in their mouths. So they couldn’t get them out again. That’s all.” + +“Thank you,” said Alice, “it’s very interesting. I never knew so much about a whiting before.” + +“I can tell you more than that, if you like,” said the Gryphon. “Do you know why it’s called a whiting?” + +“I never thought about it,” said Alice. “Why?” + +“It does the boots and shoes,” the Gryphon replied very solemnly. + +Alice was thoroughly puzzled. “Does the boots and shoes!” she repeated in a wondering tone. + +“Why, what are your shoes done with?” said the Gryphon. “I mean, what makes them so shiny?” + +Alice looked down at them, and considered a little before she gave her answer. “They’re done with blacking, I believe.” + +“Boots and shoes under the sea,” the Gryphon went on in a deep voice, “are done with a whiting. Now you know.” + +“And what are they made of?” Alice asked in a tone of great curiosity. + +“Soles and eels, of course,” the Gryphon replied rather impatiently: “any shrimp could have told you that.” + +“If I’d been the whiting,” said Alice, whose thoughts were still running on the song, “I’d have said to the porpoise, ‘Keep back, please: we don’t want you with us!’” + +“They were obliged to have him with them,” the Mock Turtle said: “no wise fish would go anywhere without a porpoise.” + +“Wouldn’t it really?” said Alice in a tone of great surprise. + +“Of course not,” said the Mock Turtle: “why, if a fish came to me, and told me he was going a journey, I should say ‘With what porpoise?’” + +“Don’t you mean ‘purpose’?” said Alice. + +“I mean what I say,” the Mock Turtle replied in an offended tone. And the Gryphon added “Come, let’s hear some of your adventures.” + +“I could tell you my adventures—beginning from this morning,” said Alice a little timidly: “but it’s no use going back to yesterday, because I was a different person then.” + +“Explain all that,” said the Mock Turtle. + +“No, no! The adventures first,” said the Gryphon in an impatient tone: “explanations take such a dreadful time.” + +So Alice began telling them her adventures from the time when she first saw the White Rabbit. She was a little nervous about it just at first, the two creatures got so close to her, one on each side, and opened their eyes and mouths so very wide, but she gained courage as she went on. Her listeners were perfectly quiet till she got to the part about her repeating “You are old, Father William,” to the Caterpillar, and the words all coming different, and then the Mock Turtle drew a long breath, and said “That’s very curious.” + +“It’s all about as curious as it can be,” said the Gryphon. + +“It all came different!” the Mock Turtle repeated thoughtfully. “I should like to hear her try and repeat something now. Tell her to begin.” He looked at the Gryphon as if he thought it had some kind of authority over Alice. + +“Stand up and repeat ‘’Tis the voice of the sluggard,’” said the Gryphon. + +“How the creatures order one about, and make one repeat lessons!” thought Alice; “I might as well be at school at once.” However, she got up, and began to repeat it, but her head was so full of the Lobster Quadrille, that she hardly knew what she was saying, and the words came very queer indeed:— + +“’Tis the voice of the Lobster; I heard him declare, +“You have baked me too brown, I must sugar my hair.” +As a duck with its eyelids, so he with his nose +Trims his belt and his buttons, and turns out his toes.” + +[later editions continued as follows +When the sands are all dry, he is gay as a lark, +And will talk in contemptuous tones of the Shark, +But, when the tide rises and sharks are around, +His voice has a timid and tremulous sound.] + +“That’s different from what I used to say when I was a child,” said the Gryphon. + +“Well, I never heard it before,” said the Mock Turtle; “but it sounds uncommon nonsense.” + +Alice said nothing; she had sat down with her face in her hands, wondering if anything would ever happen in a natural way again. + +“I should like to have it explained,” said the Mock Turtle. + +“She can’t explain it,” said the Gryphon hastily. “Go on with the next verse.” + +“But about his toes?” the Mock Turtle persisted. “How could he turn them out with his nose, you know?” + +“It’s the first position in dancing.” Alice said; but was dreadfully puzzled by the whole thing, and longed to change the subject. + +“Go on with the next verse,” the Gryphon repeated impatiently: “it begins ‘I passed by his garden.’” + +Alice did not dare to disobey, though she felt sure it would all come wrong, and she went on in a trembling voice:— + +“I passed by his garden, and marked, with one eye, +How the Owl and the Panther were sharing a pie—” + +[later editions continued as follows +The Panther took pie-crust, and gravy, and meat, +While the Owl had the dish as its share of the treat. +When the pie was all finished, the Owl, as a boon, +Was kindly permitted to pocket the spoon: +While the Panther received knife and fork with a growl, +And concluded the banquet—] + +“What is the use of repeating all that stuff,” the Mock Turtle interrupted, “if you don’t explain it as you go on? It’s by far the most confusing thing I ever heard!” + +“Yes, I think you’d better leave off,” said the Gryphon: and Alice was only too glad to do so. + +“Shall we try another figure of the Lobster Quadrille?” the Gryphon went on. “Or would you like the Mock Turtle to sing you a song?” + +“Oh, a song, please, if the Mock Turtle would be so kind,” Alice replied, so eagerly that the Gryphon said, in a rather offended tone, “Hm! No accounting for tastes! Sing her ‘Turtle Soup,’ will you, old fellow?” + +The Mock Turtle sighed deeply, and began, in a voice sometimes choked with sobs, to sing this:— + +“Beautiful Soup, so rich and green, +Waiting in a hot tureen! +Who for such dainties would not stoop? +Soup of the evening, beautiful Soup! +Soup of the evening, beautiful Soup! + Beau—ootiful Soo—oop! + Beau—ootiful Soo—oop! +Soo—oop of the e—e—evening, + Beautiful, beautiful Soup! + +“Beautiful Soup! Who cares for fish, +Game, or any other dish? +Who would not give all else for two p +ennyworth only of beautiful Soup? +Pennyworth only of beautiful Soup? + Beau—ootiful Soo—oop! + Beau—ootiful Soo—oop! +Soo—oop of the e—e—evening, + Beautiful, beauti—FUL SOUP!” + +“Chorus again!” cried the Gryphon, and the Mock Turtle had just begun to repeat it, when a cry of “The trial’s beginning!” was heard in the distance. + +“Come on!” cried the Gryphon, and, taking Alice by the hand, it hurried off, without waiting for the end of the song. + +“What trial is it?” Alice panted as she ran; but the Gryphon only answered “Come on!” and ran the faster, while more and more faintly came, carried on the breeze that followed them, the melancholy words:— + +“Soo—oop of the e—e—evening, + Beautiful, beautiful Soup!” + +CHAPTER XI. +Who Stole the Tarts? +The King and Queen of Hearts were seated on their throne when they arrived, with a great crowd assembled about them—all sorts of little birds and beasts, as well as the whole pack of cards: the Knave was standing before them, in chains, with a soldier on each side to guard him; and near the King was the White Rabbit, with a trumpet in one hand, and a scroll of parchment in the other. In the very middle of the court was a table, with a large dish of tarts upon it: they looked so good, that it made Alice quite hungry to look at them—“I wish they’d get the trial done,” she thought, “and hand round the refreshments!” But there seemed to be no chance of this, so she began looking at everything about her, to pass away the time. + +Alice had never been in a court of justice before, but she had read about them in books, and she was quite pleased to find that she knew the name of nearly everything there. “That’s the judge,” she said to herself, “because of his great wig.” + +The judge, by the way, was the King; and as he wore his crown over the wig, (look at the frontispiece if you want to see how he did it,) he did not look at all comfortable, and it was certainly not becoming. + +“And that’s the jury-box,” thought Alice, “and those twelve creatures,” (she was obliged to say “creatures,” you see, because some of them were animals, and some were birds,) “I suppose they are the jurors.” She said this last word two or three times over to herself, being rather proud of it: for she thought, and rightly too, that very few little girls of her age knew the meaning of it at all. However, “jury-men” would have done just as well. + +The twelve jurors were all writing very busily on slates. “What are they doing?” Alice whispered to the Gryphon. “They can’t have anything to put down yet, before the trial’s begun.” + +“They’re putting down their names,” the Gryphon whispered in reply, “for fear they should forget them before the end of the trial.” + +“Stupid things!” Alice began in a loud, indignant voice, but she stopped hastily, for the White Rabbit cried out, “Silence in the court!” and the King put on his spectacles and looked anxiously round, to make out who was talking. + +Alice could see, as well as if she were looking over their shoulders, that all the jurors were writing down “stupid things!” on their slates, and she could even make out that one of them didn’t know how to spell “stupid,” and that he had to ask his neighbour to tell him. “A nice muddle their slates’ll be in before the trial’s over!” thought Alice. + +One of the jurors had a pencil that squeaked. This of course, Alice could not stand, and she went round the court and got behind him, and very soon found an opportunity of taking it away. She did it so quickly that the poor little juror (it was Bill, the Lizard) could not make out at all what had become of it; so, after hunting all about for it, he was obliged to write with one finger for the rest of the day; and this was of very little use, as it left no mark on the slate. + +“Herald, read the accusation!” said the King. + +On this the White Rabbit blew three blasts on the trumpet, and then unrolled the parchment scroll, and read as follows:— + +“The Queen of Hearts, she made some tarts, + All on a summer day: +The Knave of Hearts, he stole those tarts, + And took them quite away!” + +“Consider your verdict,” the King said to the jury. + +“Not yet, not yet!” the Rabbit hastily interrupted. “There’s a great deal to come before that!” + +“Call the first witness,” said the King; and the White Rabbit blew three blasts on the trumpet, and called out, “First witness!” + +The first witness was the Hatter. He came in with a teacup in one hand and a piece of bread-and-butter in the other. “I beg pardon, your Majesty,” he began, “for bringing these in: but I hadn’t quite finished my tea when I was sent for.” + +“You ought to have finished,” said the King. “When did you begin?” + +The Hatter looked at the March Hare, who had followed him into the court, arm-in-arm with the Dormouse. “Fourteenth of March, I think it was,” he said. + +“Fifteenth,” said the March Hare. + +“Sixteenth,” added the Dormouse. + +“Write that down,” the King said to the jury, and the jury eagerly wrote down all three dates on their slates, and then added them up, and reduced the answer to shillings and pence. + +“Take off your hat,” the King said to the Hatter. + +“It isn’t mine,” said the Hatter. + +“Stolen!” the King exclaimed, turning to the jury, who instantly made a memorandum of the fact. + +“I keep them to sell,” the Hatter added as an explanation; “I’ve none of my own. I’m a hatter.” + +Here the Queen put on her spectacles, and began staring at the Hatter, who turned pale and fidgeted. + +“Give your evidence,” said the King; “and don’t be nervous, or I’ll have you executed on the spot.” + +This did not seem to encourage the witness at all: he kept shifting from one foot to the other, looking uneasily at the Queen, and in his confusion he bit a large piece out of his teacup instead of the bread-and-butter. + +Just at this moment Alice felt a very curious sensation, which puzzled her a good deal until she made out what it was: she was beginning to grow larger again, and she thought at first she would get up and leave the court; but on second thoughts she decided to remain where she was as long as there was room for her. + +“I wish you wouldn’t squeeze so.” said the Dormouse, who was sitting next to her. “I can hardly breathe.” + +“I can’t help it,” said Alice very meekly: “I’m growing.” + +“You’ve no right to grow here,” said the Dormouse. + +“Don’t talk nonsense,” said Alice more boldly: “you know you’re growing too.” + +“Yes, but I grow at a reasonable pace,” said the Dormouse: “not in that ridiculous fashion.” And he got up very sulkily and crossed over to the other side of the court. + +All this time the Queen had never left off staring at the Hatter, and, just as the Dormouse crossed the court, she said to one of the officers of the court, “Bring me the list of the singers in the last concert!” on which the wretched Hatter trembled so, that he shook both his shoes off. + +“Give your evidence,” the King repeated angrily, “or I’ll have you executed, whether you’re nervous or not.” + +“I’m a poor man, your Majesty,” the Hatter began, in a trembling voice, “—and I hadn’t begun my tea—not above a week or so—and what with the bread-and-butter getting so thin—and the twinkling of the tea—” + +“The twinkling of the what?” said the King. + +“It began with the tea,” the Hatter replied. + +“Of course twinkling begins with a T!” said the King sharply. “Do you take me for a dunce? Go on!” + +“I’m a poor man,” the Hatter went on, “and most things twinkled after that—only the March Hare said—” + +“I didn’t!” the March Hare interrupted in a great hurry. + +“You did!” said the Hatter. + +“I deny it!” said the March Hare. + +“He denies it,” said the King: “leave out that part.” + +“Well, at any rate, the Dormouse said—” the Hatter went on, looking anxiously round to see if he would deny it too: but the Dormouse denied nothing, being fast asleep. + +“After that,” continued the Hatter, “I cut some more bread-and-butter—” + +“But what did the Dormouse say?” one of the jury asked. + +“That I can’t remember,” said the Hatter. + +“You must remember,” remarked the King, “or I’ll have you executed.” + +The miserable Hatter dropped his teacup and bread-and-butter, and went down on one knee. “I’m a poor man, your Majesty,” he began. + +“You’re a very poor speaker,” said the King. + +Here one of the guinea-pigs cheered, and was immediately suppressed by the officers of the court. (As that is rather a hard word, I will just explain to you how it was done. They had a large canvas bag, which tied up at the mouth with strings: into this they slipped the guinea-pig, head first, and then sat upon it.) + +“I’m glad I’ve seen that done,” thought Alice. “I’ve so often read in the newspapers, at the end of trials, “There was some attempts at applause, which was immediately suppressed by the officers of the court,” and I never understood what it meant till now.” + +“If that’s all you know about it, you may stand down,” continued the King. + +“I can’t go no lower,” said the Hatter: “I’m on the floor, as it is.” + +“Then you may sit down,” the King replied. + +Here the other guinea-pig cheered, and was suppressed. + +“Come, that finished the guinea-pigs!” thought Alice. “Now we shall get on better.” + +“I’d rather finish my tea,” said the Hatter, with an anxious look at the Queen, who was reading the list of singers. + +“You may go,” said the King, and the Hatter hurriedly left the court, without even waiting to put his shoes on. + +“—and just take his head off outside,” the Queen added to one of the officers: but the Hatter was out of sight before the officer could get to the door. + +“Call the next witness!” said the King. + +The next witness was the Duchess’s cook. She carried the pepper-box in her hand, and Alice guessed who it was, even before she got into the court, by the way the people near the door began sneezing all at once. + +“Give your evidence,” said the King. + +“Shan’t,” said the cook. + +The King looked anxiously at the White Rabbit, who said in a low voice, “Your Majesty must cross-examine this witness.” + +“Well, if I must, I must,” the King said, with a melancholy air, and, after folding his arms and frowning at the cook till his eyes were nearly out of sight, he said in a deep voice, “What are tarts made of?” + +“Pepper, mostly,” said the cook. + +“Treacle,” said a sleepy voice behind her. + +“Collar that Dormouse,” the Queen shrieked out. “Behead that Dormouse! Turn that Dormouse out of court! Suppress him! Pinch him! Off with his whiskers!” + +For some minutes the whole court was in confusion, getting the Dormouse turned out, and, by the time they had settled down again, the cook had disappeared. + +“Never mind!” said the King, with an air of great relief. “Call the next witness.” And he added in an undertone to the Queen, “Really, my dear, you must cross-examine the next witness. It quite makes my forehead ache!” + +Alice watched the White Rabbit as he fumbled over the list, feeling very curious to see what the next witness would be like, “—for they haven’t got much evidence yet,” she said to herself. Imagine her surprise, when the White Rabbit read out, at the top of his shrill little voice, the name “Alice!” + +CHAPTER XII. +Alice’s Evidence +“Here!” cried Alice, quite forgetting in the flurry of the moment how large she had grown in the last few minutes, and she jumped up in such a hurry that she tipped over the jury-box with the edge of her skirt, upsetting all the jurymen on to the heads of the crowd below, and there they lay sprawling about, reminding her very much of a globe of goldfish she had accidentally upset the week before. + +“Oh, I beg your pardon!” she exclaimed in a tone of great dismay, and began picking them up again as quickly as she could, for the accident of the goldfish kept running in her head, and she had a vague sort of idea that they must be collected at once and put back into the jury-box, or they would die. + +“The trial cannot proceed,” said the King in a very grave voice, “until all the jurymen are back in their proper places—all,” he repeated with great emphasis, looking hard at Alice as he said so. + +Alice looked at the jury-box, and saw that, in her haste, she had put the Lizard in head downwards, and the poor little thing was waving its tail about in a melancholy way, being quite unable to move. She soon got it out again, and put it right; “not that it signifies much,” she said to herself; “I should think it would be quite as much use in the trial one way up as the other.” + +As soon as the jury had a little recovered from the shock of being upset, and their slates and pencils had been found and handed back to them, they set to work very diligently to write out a history of the accident, all except the Lizard, who seemed too much overcome to do anything but sit with its mouth open, gazing up into the roof of the court. + +“What do you know about this business?” the King said to Alice. + +“Nothing,” said Alice. + +“Nothing whatever?” persisted the King. + +“Nothing whatever,” said Alice. + +“That’s very important,” the King said, turning to the jury. They were just beginning to write this down on their slates, when the White Rabbit interrupted: “Unimportant, your Majesty means, of course,” he said in a very respectful tone, but frowning and making faces at him as he spoke. + +“Unimportant, of course, I meant,” the King hastily said, and went on to himself in an undertone, + +“important—unimportant—unimportant—important—” as if he were trying which word sounded best. + +Some of the jury wrote it down “important,” and some “unimportant.” Alice could see this, as she was near enough to look over their slates; “but it doesn’t matter a bit,” she thought to herself. + +At this moment the King, who had been for some time busily writing in his note-book, cackled out “Silence!” and read out from his book, “Rule Forty-two. All persons more than a mile high to leave the court.” + +Everybody looked at Alice. + +“I’m not a mile high,” said Alice. + +“You are,” said the King. + +“Nearly two miles high,” added the Queen. + +“Well, I shan’t go, at any rate,” said Alice: “besides, that’s not a regular rule: you invented it just now.” + +“It’s the oldest rule in the book,” said the King. + +“Then it ought to be Number One,” said Alice. + +The King turned pale, and shut his note-book hastily. “Consider your verdict,” he said to the jury, in a low, trembling voice. + +“There’s more evidence to come yet, please your Majesty,” said the White Rabbit, jumping up in a great hurry; “this paper has just been picked up.” + +“What’s in it?” said the Queen. + +“I haven’t opened it yet,” said the White Rabbit, “but it seems to be a letter, written by the prisoner to—to somebody.” + +“It must have been that,” said the King, “unless it was written to nobody, which isn’t usual, you know.” + +“Who is it directed to?” said one of the jurymen. + +“It isn’t directed at all,” said the White Rabbit; “in fact, there’s nothing written on the outside.” He unfolded the paper as he spoke, and added “It isn’t a letter, after all: it’s a set of verses.” + +“Are they in the prisoner’s handwriting?” asked another of the jurymen. + +“No, they’re not,” said the White Rabbit, “and that’s the queerest thing about it.” (The jury all looked puzzled.) + +“He must have imitated somebody else’s hand,” said the King. (The jury all brightened up again.) + +“Please your Majesty,” said the Knave, “I didn’t write it, and they can’t prove I did: there’s no name signed at the end.” + +“If you didn’t sign it,” said the King, “that only makes the matter worse. You must have meant some mischief, or else you’d have signed your name like an honest man.” + +There was a general clapping of hands at this: it was the first really clever thing the King had said that day. + +“That proves his guilt,” said the Queen. + +“It proves nothing of the sort!” said Alice. “Why, you don’t even know what they’re about!” + +“Read them,” said the King. + +The White Rabbit put on his spectacles. “Where shall I begin, please your Majesty?” he asked. + +“Begin at the beginning,” the King said gravely, “and go on till you come to the end: then stop.” + +These were the verses the White Rabbit read:— + +“They told me you had been to her, + And mentioned me to him: +She gave me a good character, + But said I could not swim. + +He sent them word I had not gone + (We know it to be true): +If she should push the matter on, + What would become of you? + +I gave her one, they gave him two, + You gave us three or more; +They all returned from him to you, + Though they were mine before. + +If I or she should chance to be + Involved in this affair, +He trusts to you to set them free, + Exactly as we were. + +My notion was that you had been + (Before she had this fit) +An obstacle that came between + Him, and ourselves, and it. + +Don’t let him know she liked them best, + For this must ever be +A secret, kept from all the rest, + Between yourself and me.” + +“That’s the most important piece of evidence we’ve heard yet,” said the King, rubbing his hands; “so now let the jury—” + +“If any one of them can explain it,” said Alice, (she had grown so large in the last few minutes that she wasn’t a bit afraid of interrupting him,) “I’ll give him sixpence. I don’t believe there’s an atom of meaning in it.” + +The jury all wrote down on their slates, “She doesn’t believe there’s an atom of meaning in it,” but none of them attempted to explain the paper. + +“If there’s no meaning in it,” said the King, “that saves a world of trouble, you know, as we needn’t try to find any. And yet I don’t know,” he went on, spreading out the verses on his knee, and looking at them with one eye; “I seem to see some meaning in them, after all. “—said I could not swim—” you can’t swim, can you?” he added, turning to the Knave. + +The Knave shook his head sadly. “Do I look like it?” he said. (Which he certainly did not, being made entirely of cardboard.) + +“All right, so far,” said the King, and he went on muttering over the verses to himself: “‘We know it to be true—’ that’s the jury, of course—‘I gave her one, they gave him two—’ why, that must be what he did with the tarts, you know—” + +“But, it goes on ‘they all returned from him to you,’” said Alice. + +“Why, there they are!” said the King triumphantly, pointing to the tarts on the table. “Nothing can be clearer than that. Then again—‘before she had this fit—’ you never had fits, my dear, I think?” he said to the Queen. + +“Never!” said the Queen furiously, throwing an inkstand at the Lizard as she spoke. (The unfortunate little Bill had left off writing on his slate with one finger, as he found it made no mark; but he now hastily began again, using the ink, that was trickling down his face, as long as it lasted.) + +“Then the words don’t fit you,” said the King, looking round the court with a smile. There was a dead silence. + +“It’s a pun!” the King added in an offended tone, and everybody laughed, “Let the jury consider their verdict,” the King said, for about the twentieth time that day. + +“No, no!” said the Queen. “Sentence first—verdict afterwards.” + +“Stuff and nonsense!” said Alice loudly. “The idea of having the sentence first!” + +“Hold your tongue!” said the Queen, turning purple. + +“I won’t!” said Alice. + +“Off with her head!” the Queen shouted at the top of her voice. Nobody moved. + +“Who cares for you?” said Alice, (she had grown to her full size by this time.) “You’re nothing but a pack of cards!” + +At this the whole pack rose up into the air, and came flying down upon her: she gave a little scream, half of fright and half of anger, and tried to beat them off, and found herself lying on the bank, with her head in the lap of her sister, who was gently brushing away some dead leaves that had fluttered down from the trees upon her face. + +“Wake up, Alice dear!” said her sister; “Why, what a long sleep you’ve had!” + +“Oh, I’ve had such a curious dream!” said Alice, and she told her sister, as well as she could remember them, all these strange Adventures of hers that you have just been reading about; and when she had finished, her sister kissed her, and said, “It was a curious dream, dear, certainly: but now run in to your tea; it’s getting late.” So Alice got up and ran off, thinking while she ran, as well she might, what a wonderful dream it had been. + +But her sister sat still just as she left her, leaning her head on her hand, watching the setting sun, and thinking of little Alice and all her wonderful Adventures, till she too began dreaming after a fashion, and this was her dream:— + +First, she dreamed of little Alice herself, and once again the tiny hands were clasped upon her knee, and the bright eager eyes were looking up into hers—she could hear the very tones of her voice, and see that queer little toss of her head to keep back the wandering hair that would always get into her eyes—and still as she listened, or seemed to listen, the whole place around her became alive with the strange creatures of her little sister’s dream. + +The long grass rustled at her feet as the White Rabbit hurried by—the frightened Mouse splashed his way through the neighbouring pool—she could hear the rattle of the teacups as the March Hare and his friends shared their never-ending meal, and the shrill voice of the Queen ordering off her unfortunate guests to execution—once more the pig-baby was sneezing on the Duchess’s knee, while plates and dishes crashed around it—once more the shriek of the Gryphon, the squeaking of the Lizard’s slate-pencil, and the choking of the suppressed guinea-pigs, filled the air, mixed up with the distant sobs of the miserable Mock Turtle. + +So she sat on, with closed eyes, and half believed herself in Wonderland, though she knew she had but to open them again, and all would change to dull reality—the grass would be only rustling in the wind, and the pool rippling to the waving of the reeds—the rattling teacups would change to tinkling sheep-bells, and the Queen’s shrill cries to the voice of the shepherd boy—and the sneeze of the baby, the shriek of the Gryphon, and all the other queer noises, would change (she knew) to the confused clamour of the busy farm-yard—while the lowing of the cattle in the distance would take the place of the Mock Turtle’s heavy sobs. + +Lastly, she pictured to herself how this same little sister of hers would, in the after-time, be herself a grown woman; and how she would keep, through all her riper years, the simple and loving heart of her childhood: and how she would gather about her other little children, and make their eyes bright and eager with many a strange tale, perhaps even with the dream of Wonderland of long ago: and how she would feel with all their simple sorrows, and find a pleasure in all their simple joys, remembering her own child-life, and the happy summer days. + +THE END""" \ No newline at end of file diff --git a/python-csi160/week10/part1.py b/python-csi160/week10/part1.py new file mode 100644 index 0000000..eaf0239 --- /dev/null +++ b/python-csi160/week10/part1.py @@ -0,0 +1,39 @@ + +# Step 1. Create dictionary called 'user' +# with the following keys: 'name' and 'location' +# Set the name to 'John Doe' +# Set the location to 'Burlington, VT' + +user = { + 'name': 'John Doe', + 'location': 'Burlington, VT' +} + +# Step 2. Ask the user for the user's age +# and create a key/value pair in user to store this +# called 'age' +try: + age = input(f"How old is {user['name']}? ") +except KeyError: + print('"name" not defined as a key in Step 1') +else: + user['age'] = int(age) + print(f"{user['name']} is {user['age']} years old.") + + +# Step 3 +# Create keys "first_name" and "last_name" +# Use .split() to seperate name into firstname and last_name +# Remove the key "name" from the dictionary + +first_name, last_name = user['name'].split() +user['first_name'] = first_name +user['last_name'] = last_name +del user['name'] +print(f"First name: {user['first_name']}") +print(f"Last name: {user['last_name']}") + + +# For testing (do not delete) +print('Printing "user":') +print(user) diff --git a/python-csi160/week10/part2.py b/python-csi160/week10/part2.py new file mode 100644 index 0000000..9ea79c6 --- /dev/null +++ b/python-csi160/week10/part2.py @@ -0,0 +1,25 @@ +def synonym_lookup(word_pairs, word_to_lookup): + """Returns synonym for the word to word_to_lookup + + Complete this function by using a dictionary. For each synonym pair, + you should add both words as keys to your dictionary with the value being the other word. + + params: + word_pairs (tuple of tuples): Example: (('Hello', 'Hi'), ('Goodbye','Bye')) + word_to_lookup (string): The word to find a synonym for + return (string): The synonym for the word_to_lookup + """ + synonym_dict = {} + + # Create a dictionary with both words in each pair + for word1, word2 in word_pairs: + synonym_dict[word1] = word2 + synonym_dict[word2] = word1 + + # Return the synonym + return synonym_dict.get(word_to_lookup, None) + + +example_word_pairs = (('Hello', 'Hi'), ('Goodbye','Bye'), ('Snake', 'Serpent')) + +print(f'A synonym for "Serpent" is {synonym_lookup(example_word_pairs, "Serpent")}. (Snake expected)') diff --git a/python-csi160/week10/part3.py b/python-csi160/week10/part3.py new file mode 100644 index 0000000..5ffa495 --- /dev/null +++ b/python-csi160/week10/part3.py @@ -0,0 +1,38 @@ +final_election_results = {} + +def record_candidate_votes(election_results, candidate, num_votes, precinct): + """Records votes for a particular candidate in one precinct in the election_results. + + The precinct is not used for the function currently. + + Optional tip: Using method .get() can allow you to avoid needing a if or try statement + + params: + election_results (dict): Dictionary to be modified by recording the votes for a candidate in a precinct + cadidate (string): The name of a candidate. Used as the 'key' in the election_results dictionary. + num_votes (int): The number of votes to add to the candidate's total + """ + if candidate in election_results: + # If candidate exists, add to the existing total + election_results[candidate] += num_votes + else: + # If candidate doesn't exist, create a new entry + election_results[candidate] = num_votes + + + +# This section is for testing purposes, do not modify +# FYI: These numbers are made up for example purposes only +record_candidate_votes(final_election_results,'Miro Weinberger', 100, 'Ward 1') +record_candidate_votes(final_election_results,'Max Tracy', 140, 'Ward 1') +record_candidate_votes(final_election_results,'Ali Dieng', 27, 'Ward 1') +record_candidate_votes(final_election_results,'Miro Weinberger', 50, 'Ward 2') +record_candidate_votes(final_election_results,'Max Tracy', 150, 'Ward 2') +record_candidate_votes(final_election_results,'Ali Dieng', 35, 'Ward 2') +record_candidate_votes(final_election_results,'Miro Weinberger', 100, 'Ward 3') +record_candidate_votes(final_election_results,'Max Tracy', 100, 'Ward 3') +record_candidate_votes(final_election_results,'Ali Dieng', 56, 'Ward 3') +record_candidate_votes(final_election_results,'Miro Weinberger', 320, 'Ward 4') +record_candidate_votes(final_election_results,'Max Tracy', 213, 'Ward 4') +record_candidate_votes(final_election_results,'Ali Dieng', 175, 'Ward 4') +print(final_election_results) \ No newline at end of file diff --git a/python-csi160/week10/part4.py b/python-csi160/week10/part4.py new file mode 100644 index 0000000..c895972 --- /dev/null +++ b/python-csi160/week10/part4.py @@ -0,0 +1,45 @@ +import string +from alice import alice_text + +def word_frequency(text): + """Generates a word frequency dictionary for the supplied text. All punctuation is stripped and the case is converted to lowercase. + + Example dictionary: {'the': 2, 'cat': 1, 'bit': 1, 'dog': 1} + + param text: (string) The text to be analyzed + return: (dict) Word frequency dictionary + """ + # Strip Punctuation + for character in string.punctuation: + text = text.replace(character, "") + + # Convert to lower case + text = text.lower() + + # Generate a list of all of the words + words = text.split() + + word_frequency = {} + for word in words: + if word in word_frequency: + word_frequency[word] += 1 + else: + word_frequency[word] = 1 + return word_frequency + + +# Code for testing purposes. Do not modify +short_sentence = "The silly cat is the silly face." +print(f'Analyzing word frequency of "{short_sentence}"') +print(word_frequency("The silly cat is the silly face.")) + +print() +try: + print('In Alice and Wonderland,') + alice_freq = word_frequency(alice_text) + print(f'The word Alice occurs {alice_freq["alice"]} times') + print(f'The word melancholy occurs {alice_freq["melancholy"]} times') + print(f'{len(alice_freq)} different words are used in the book.') +except Exception as e: + print('Exception raised when analyzing Alice in Wonderland:') + print(e) diff --git a/sysadmin-i-sys255/CA_process.png b/sysadmin-i-sys255/CA_process.png new file mode 100644 index 0000000..47b3f84 Binary files /dev/null and b/sysadmin-i-sys255/CA_process.png differ diff --git a/sysadmin-i-sys255/README.md b/sysadmin-i-sys255/README.md new file mode 100644 index 0000000..7df62f4 --- /dev/null +++ b/sysadmin-i-sys255/README.md @@ -0,0 +1,17 @@ +# System Administration I +Spring 2024 + +- week01 - [Environment Setup](https://git.charlotte.sh/lotte/ChamplainTechJournals/src/branch/main/sysadmin-i-sys255/lab01-environment-setup.md) +- week02 - [DNS+ADDS](https://git.charlotte.sh/lotte/ChamplainTechJournals/src/branch/main/sysadmin-i-sys255/lab02-dns%2Badds-role.md) +- week03 - [Linux Intro](https://git.charlotte.sh/lotte/ChamplainTechJournals/src/branch/main/sysadmin-i-sys255/lab03-linux.md) +- week04 - [Linux DHCP](https://git.charlotte.sh/lotte/ChamplainTechJournals/src/branch/main/sysadmin-i-sys255/lab04-dhcp.md) +- week05 - [ADDS & Group Policy](https://git.charlotte.sh/lotte/ChamplainTechJournals/src/branch/main/sysadmin-i-sys255/lab05-adds-and-group-policy.md) +- week06 - [Midterm](https://git.charlotte.sh/lotte/ChamplainTechJournals/src/branch/main/sysadmin-i-sys255/lab06-midterm.md) +- week07 - [Server Core & RAT](https://git.charlotte.sh/lotte/ChamplainTechJournals/src/branch/main/sysadmin-i-sys255/lab07-lab-server-core-and-remote-administrator-tools.md) +- week08 - [Apache](https://git.charlotte.sh/lotte/ChamplainTechJournals/src/branch/main/sysadmin-i-sys255/lab08-apache.md) +- week8.5- [Windows DHCP](https://git.charlotte.sh/lotte/ChamplainTechJournals/src/branch/main/sysadmin-i-sys255/lab08.5-configure-windows-dhcp-server.md) +- week09 - [BASH Intro](https://git.charlotte.sh/lotte/ChamplainTechJournals/src/branch/main/sysadmin-i-sys255/lab09-bash-scripting.md) +- week10 - [PowerShell Intro](https://git.charlotte.sh/lotte/ChamplainTechJournals/src/branch/main/sysadmin-i-sys255/lab10-powershell.md) +- week11 - [Wordpress on Linux](https://git.charlotte.sh/lotte/ChamplainTechJournals/src/branch/main/sysadmin-i-sys255/lab11-wordpress-on-linux.md) +- week12 - [Automation Intro](https://git.charlotte.sh/lotte/ChamplainTechJournals/src/branch/main/sysadmin-i-sys255/lab12-automation.md) +- week13 - [Wordpress on Windows](https://git.charlotte.sh/lotte/ChamplainTechJournals/src/branch/main/sysadmin-i-sys255/lab13-wordpress-on-windows.md) diff --git a/sysadmin-i-sys255/SYS255_NetworkDiagram.drawio b/sysadmin-i-sys255/SYS255_NetworkDiagram.drawio new file mode 100644 index 0000000..497addd --- /dev/null +++ b/sysadmin-i-sys255/SYS255_NetworkDiagram.drawio @@ -0,0 +1,85 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sysadmin-i-sys255/lab01-environment-setup.md b/sysadmin-i-sys255/lab01-environment-setup.md new file mode 100644 index 0000000..2fb3d13 --- /dev/null +++ b/sysadmin-i-sys255/lab01-environment-setup.md @@ -0,0 +1,81 @@ +--- +description: >- + In this lab, we set up our Windows workstation and PfSense firewall on + vSphere. +--- + +# Lab01 - Environment Setup + +## Add a Network Adapters in VSphere: +- Power off the machine +- VM Hardware Section -> Edit +- Add New Device -> Network Adapter +- Change interface to either WAN or LAN + + +## FW01 +Before powering on, check the network interface configuration (1:WAN 2:LAN) + +### Configure IP Addresses +- Should VLANs be set up no: **n** +- Enter the WAN interface name: **em0** +- Enter the LAN interface name:**em1** +- Do you want to proceed:**y** + +- Select Option 2 to Set IP Addresses, Pick 1 - WAN em0 +- Configure IPv4 address WAN interface via DHCP?: **n** +- Enter your new WAN IPv4 address: **10.0.17.104** +- Enter the new WAN IPv4 subnet bit count: **24** +- For WAN enter the new IPv4 upstream gateway address of **10.0.17.2** +- Configure IPv6 address WAN interface via DHCP6?: **n** +- Enter the new WAN IPv6 address: ** for none** +- Do you want to revert to HTTP as the webConfigurator protocol? : **n** +The console screen should now show a static IP address of 10.0.17.104/24 for em0: + + +Now we need to set the IP address for the other interface em1. +Select Option 2 again. +- Pick interface 2 - LAN (em1) +- Enter the new LAN IPv4 address: **10.0.5.2** +- Enter the new LAN IPv4 subnet bit count: **24** +- For a LAN press for none: **** +- Enter the LAN IPv6 address: **** +- Do you want to enable the DHCP server on LAN?: **n** +- Do you want to revert to HTTP as the webConfigurator protocol? : **n** + +![image](../assets/5bde20db-9f06-4891-b5f1-22cea0ab2014.png) + + +## WKS01 + +### Rename this Windows Computer +* In File Explorer, right-click on “This PC” +* “Properties” -> “Change Settings” +* Click “Change” next to “To rename this computer…” +* rename to `wks01-charlotte` + +### Add a user +* Computer Management -> Local Users and Groups -> Users +* Right Click -> New User +* `charlotte:password123` +![image](../assets/383fc178-8815-4a57-90f3-7138d8bbf02b.png) + +### Add a User to a Group +* Go to user Properties -> Member Of -> Add +* Type the group name: `WKS01-CHARLOTTE\Adminstrators` +* Check names, if the text entered is a valid group, the text should underline + +### Change IP Address +* Go to Network and Internet settings -> Change adapter options +* Right-click on network adapter - “properties” +* Double-click IPv4 setting +![image](../assets/1b3f68db-04b0-42dc-837e-c9d0623132d4.png) + + +### PFSense GUI (web) +The default username/password is admin/pfsense + +![image](../assets/cb27b4f7-abd2-489e-a465-fadf7005c57a.png) +![image](../assets/1ea4dc4a-a2e4-4518-ae35-6ad320a8cf06.png) + +new admin password: password123 diff --git a/sysadmin-i-sys255/lab02-dns+adds-role.md b/sysadmin-i-sys255/lab02-dns+adds-role.md new file mode 100644 index 0000000..b86de2d --- /dev/null +++ b/sysadmin-i-sys255/lab02-dns+adds-role.md @@ -0,0 +1,53 @@ +--- +description: >- + In this lab, we created an Active Directory Domain Server on our Windows 2019 + Server (10.0.5.5) +--- + +# Lab02 - DNS+ADDS Role + +## Domain vs. Local Administrator + +Local administrators have power within the singular Windows OS, while Domain administrators have power over items within the AD domain + +## Installing the ADDS Role on Windows Server + +* go to Server manager +* Manage -> Add Roles and Features +* check `Active Directory Domain Services` and install dependencies as well +* continue through wizard and install + +## Configure our server to be the primary domain controller for our domain + +* click `Promote this server to a domain controller` +* `Add a new forest` - nathan.local +* set DSRM password +* continue through wizard and install + +## Create Forward Lookup DNS Records + +* go to DNS Manager +* DNS -> ad01-nathan.nathan.local -> Forward Lookup Zones -> right click nathan.local -> New Host +* PTR records will not work right now /bc there is no reverse lookup zone + +## Create Reverse Lookup DNS Records + +* go to DNS Manager +* DNS -> ad01-nathan.nathan.local -> right click Reverse Lookup Zones -> New Zone +* enter Network ID (10.0.5.) when prompted +* update PTR records on A records, refresh, and PTR records should appear in Reverse Lookup Zones + +## Create a user in AD + +* server manager -> AD DS -> right click server -> Active Directory Users and Computers +* nathan.local -> right-click Users -> New -> User + +## Add a user to the domain admin group + +* right click created user -> add to a group +* type 'Domain Admins' + +## Add a computer to the domain + +* control panel -> system and security -> system -> change settings +* change from workgroup to domain diff --git a/sysadmin-i-sys255/lab03-linux.md b/sysadmin-i-sys255/lab03-linux.md new file mode 100644 index 0000000..7524b85 --- /dev/null +++ b/sysadmin-i-sys255/lab03-linux.md @@ -0,0 +1,27 @@ +--- +description: >- + In this lab we set up the DHCP server in Linux, but we haven't added any DHCP + functionality yet, just networking configurations and adding a user +--- + +# Lab03 - Linux Setup + +## mntui +* network manager TUI +* used to set up network configuration & can change hostname +* (remember to set search domain to charlotte.local) +* `systemctl restart network` or `systemctl restart NetworkManager` to restart network after config change + + +## set hostname +`hostnamectl set-hostname dhcp01-charlotte` + +## creating privileged user +* `useradd charlotte` +* `passwd charlotte` +* `usermod -aG (wheel/sudo) charlotte` - RH=wheel, Debain=sudo + + +## ipconfig DNS commands +* `/flushdns`: clears DNS cache and forces the computer to regain all DNS entries from the DNS server +* `/registerdns`: re-registers all domain names and IP addresses diff --git a/sysadmin-i-sys255/lab04-dhcp.md b/sysadmin-i-sys255/lab04-dhcp.md new file mode 100644 index 0000000..16ed85f --- /dev/null +++ b/sysadmin-i-sys255/lab04-dhcp.md @@ -0,0 +1,95 @@ +--- +description: >- + this week we configured dhcp01-nathan to run the dhcp server. now wks01 uses + dhcp rather than static IP assignment +--- + +# Lab04 - DHCP + +## DHCP configuration + +* connect to dhcp01-nathan via puTTY +* `sudo yum install dhcp` +* configure `/etc/dhcp/dhcpd.conf` file + +![alt text](../assets/lab04sys255.png) + +* start\&enable dhcp +* configure dhcp on firewall +* configure wks01-nathan to use DHCP instead of static IP + +#### to start dhcp + +`systemctl start dhcpd` + +#### to check status of dhcp + +`systemctl status dhcpd` + +#### configure dhcp to start on boot + +`systemctl enable dhcpd` + +#### configure dhcp on firewall + +* `firewall-cmd --add-service=dhcp --permanent` +* `firewall-cmd --reload` +* `firewall-cmd --list-all` + +#### search for dhcp logs from wks01-nathan + +`sudo cat /var/log/messages | grep wks01-nathan` + +#### release dhcp + +`ipconfig /release` + +#### renew dhcp + +`ipconfig /renew` + +#### filtering dhcp messages in wireshark + +`udp.port==67` + +## Disable root access via ssh + +* `nano /etc/ssh/sshd_config` +* change `PermitRootLogin` from yes to no and uncomment +* `systemctl restart sshd` + +## File Permissions + +#### how to create a group + +`groupadd [groupname]` + +#### how to add a user to a group + +`usermod -aG [groupname] [username]` + +#### how to change the owner of a file + +`chown filename [username]` + +#### how to change the group of file + +`chgrp filename [groupname]` + +## Changing file permissions + +#### Method 1: using bit values + +* Read: 4 +* Write: 2 +* Execute: 1 Add up the numbers to set permissions for each accessor (owner/group/everyone else) + +example: `chmod 640 file.txt` give read/write to owners, read to group members, and no access to everyone else + +#### Method 2: adding/removing file permissions individually + +* `chmod u+/-(r/w/x) [filename]` - users (owner) +* `chmod g+/-(r/w/x) [filename]` - group +* `chmod o+/-(r/w/x) [filename]` - others (everyone else) + +example: `chmod g+w file.txt` gives write permissions to the group of `file.txt` diff --git a/sysadmin-i-sys255/lab05-adds-and-group-policy.md b/sysadmin-i-sys255/lab05-adds-and-group-policy.md new file mode 100644 index 0000000..9aaf9ea --- /dev/null +++ b/sysadmin-i-sys255/lab05-adds-and-group-policy.md @@ -0,0 +1,44 @@ +--- +description: This week we created organizational units and group policy on our AD server +--- + +# Lab05 - ADDS & Group Policy + +### Create organizational units and add users/computers/groups + +* Server Manager -> Active Directory Users and Computers +* rc nathan.local -> new -> Organizational Unit (named SYS255) +* rc SYS255, create three child OUs (Accounts, Computers, and Groups) +* add users Alice, Bob, and Charlie to SYS255/Accounts (default password is Pass123!) +* move WKS01-NATHAN from nathan.local/Computers to nathan.local/SYS255/Computers +* within the SYS255\Groups OU, add a global security group called custom-desktop with users Alice and Bob (not Charlie) as members + +### Create group policy + +* Server Manager -> Group Policy Management +* rc nathan.local/SYS255 -> Create GPO in this domain... (name it sys255-desktop) +* click sys255-desktop, under Security Filtering, add the custom-desktop global security group +* remove Authenticated Users +* add Domain Computers + +* Delegation tab -> Advanced -> Domain Computers -> Uncheck Apply Group Policy and Select Deny + +### Edit group policy + +* rc sys255-desktop - > Edit + +#### remove the recycling bin + +![image](../assets/lab05-1.png) + +#### disable last login + +* create a GPO under SYS255/Computers +* aplly security filtering to only domain computers +* rc DisableLastLogin -> Edit + +### Useful commands + +`gpresult /r` - shows a summary of group policy on a workstation\ +`gpresult /scope computer /r` - shows a summary of computer-specific group policy\ +`gpupdate /force` - forces a group policy update diff --git a/sysadmin-i-sys255/lab06-midterm.md b/sysadmin-i-sys255/lab06-midterm.md new file mode 100644 index 0000000..379c278 --- /dev/null +++ b/sysadmin-i-sys255/lab06-midterm.md @@ -0,0 +1,8 @@ +--- +description: >- + In this lab, we rebuilt the network so far using our notes from the first 5 + labs. Some IP addresses were changed +--- + +# Lab06 - Midterm + diff --git a/sysadmin-i-sys255/lab07-lab-server-core-and-remote-administrator-tools.md b/sysadmin-i-sys255/lab07-lab-server-core-and-remote-administrator-tools.md new file mode 100644 index 0000000..2828ac1 --- /dev/null +++ b/sysadmin-i-sys255/lab07-lab-server-core-and-remote-administrator-tools.md @@ -0,0 +1,44 @@ +# Lab07 - Lab Server Core & Remote Administrator Tools + +### Join FS01-nathan to domain + +* `sconfig` - server configuration +* edit default configs to match the screenshots below + +![image](../assets/lab07-1.png) + +* join domain nathan.local using nathan.croce-adm user + +### Allow AD02 remote access to FS01 + +* on AD02 - server manager - manage - add roles and features +* skip to features section +* check remote server administration tools / role administration tools / file services tools / file server resource manager tools +* install +* add FS01 to all servers + +### Use RSAT to add to FS01 and create a Sales Users share + +* on AD02 - all servers - rc FS01 - add roles and features +* skip to server roles +* file and storage services / file and iSCSI services / check file server & file server resource manager +* install +* Run the following Net Shell command on fs01 to open the firewall for managing the File Server `netsh advfirewall firewall set rule group=”Remote File Server Resource Manager Management” new enable=yes` +* on AD02 - Server Manager - file and storage services - servers - rc fs01 - file server resource manager +* on AD02 - Server Manager - file and storage services - shares - new share +* SMB quick share - located on FS01 + + +* skip to create +* edit permissions and give sales-users full control over share + + +### mapping network share to drive letter + +* on AD02 - group policy management - ... - SYS255 - groups - Create GPO and link it here (I name it 'Mapped Drive') +* check enforced on the GPO + +* edit GPO +* User Configuration -> Preferences -> Windows Settings -> Drive Mappings - rc Drive Maps - new - mapped drive +* common tab - targeting +* new item - organization unit diff --git a/sysadmin-i-sys255/lab08-apache.md b/sysadmin-i-sys255/lab08-apache.md new file mode 100644 index 0000000..e869708 --- /dev/null +++ b/sysadmin-i-sys255/lab08-apache.md @@ -0,0 +1,41 @@ +--- +description: In this lab, we set up an Apache web server on WEB01 +--- + +# Lab08 - Apache + +## Apache Server Installation & Configuration + +### Configure WEB01 + +* `nmtui` +* IP address is 10.0.5.10 +* setting alternate DNS to 8.8.8.8 made initial connectivity work (idk why) +* remember to add A and PTR records to DNS server + +### Install httpd + +```bash +sudo yum install httpd +sudo firewall-cmd --add-service=http --permanent +sudo firewall-cmd --add-service=https --permanent +sudo firewall-cmd --reload +sudo systemctl start httpd +sudo systemctl enable httpd +``` + +* comment out all lines in `/etc/httpd/conf.d/welcome.conf` +* add _index.html_ file to `/var/www/html/` +* the contents of _index.html_ should be what searching `http://web01-nathan` in a browser will give you + +### Install PHP + +* `yum install -y php` +* `systemctl restart httpd` +* add _index.php_ file to `/var/www/html/` + +## Linux Domain Join + +* `sudo yum install -y realmd samba samba-common oddjob oddjob-mkhomedir sssd` +* `sudo realm join --user=nathan.croce-adm@nathan.local nathan.local` +* `realm list` diff --git a/sysadmin-i-sys255/lab08.5-configure-windows-dhcp-server.md b/sysadmin-i-sys255/lab08.5-configure-windows-dhcp-server.md new file mode 100644 index 0000000..f2d9d93 --- /dev/null +++ b/sysadmin-i-sys255/lab08.5-configure-windows-dhcp-server.md @@ -0,0 +1,26 @@ +--- +description: In this lab, we configured a Windows DHCP server on FS01 via RSAT from AD02 +--- + +# Lab08.5 - Configure Windows DHCP Server + +## Install DHCP on FS01 + +* AD02 - all servers - rc FS01 - Add Roles and Features +* roles - check DHCP server +* continue to install +* complete DHCP configuration + +## Add RSAT to AD02 + +* Add Roles and Features +* select AD02 +* Features - Remote Server Administration Tools - Remote Server Administration Tools - DHCP Server Tools +* continue to install + +## Configure DHCP on FS01 + +* rc FS01 - DHCP Manager +* add server - select FS01 +* rc IPv4 - New Scope +* configs are pretty self-explanatory (remember to add 10.0.5.6 to DNS) diff --git a/sysadmin-i-sys255/lab09-bash-scripting.md b/sysadmin-i-sys255/lab09-bash-scripting.md new file mode 100644 index 0000000..ae7ceaf --- /dev/null +++ b/sysadmin-i-sys255/lab09-bash-scripting.md @@ -0,0 +1,25 @@ +--- +description: In this lab, we explored basic BASH scripting +--- + +# Lab09 - BASH Scripting + +## Commands to find Information on BASH Environment + +* `bash -version | grep version` - BASH version installed +* `which bash` - where the BASH program resides +* `echo $PATH` - [Path Environment Variable](https://en.wikipedia.org/wiki/PATH\_\(variable\)) +* `env` - [Environment Variables](https://www.techrepublic.com/article/linux-101-what-are-environment-variables/) +* `history` - shows previous commands executed + +## Check if substring is in string + +`if [[ $string =~ "substring" ]]; then` + +* Ping sweeper script + +
+ +* nslookup script + +
diff --git a/sysadmin-i-sys255/lab10-powershell.md b/sysadmin-i-sys255/lab10-powershell.md new file mode 100644 index 0000000..3615eb6 --- /dev/null +++ b/sysadmin-i-sys255/lab10-powershell.md @@ -0,0 +1,29 @@ +--- +description: In this lab, we explored basic PowerShell scripting +--- + +# Lab10 - PowerShell + +## AD Commands + +* `Neq-ADUser -Name "Charlie" -SamAccountName "charlie" - AccountPassword(Read-Host -AsSecureString "Password: ") -Enabled $true` +* `Add-ADGroupMember -Identity "Sales-Users" - Members charlie` + +
+ +## Allow PS Scripts to be Run + +* `Set-ExecutionPolicy -Scope CurrentUser RemoteSigned` +* This allows current users to run local scripts and digitally signed remote scripts + +## Remote Access + +* `Enter-PSSession -ComputerName ` - interactive remote session + +
+ +* `Invoke-Command -ComputerName -ScriptBlock { }` - launch a command remotely + +
+ +* `Enable-PSRemoting` - allows remote commands to be executed on this machine diff --git a/sysadmin-i-sys255/lab11-wordpress-on-linux.md b/sysadmin-i-sys255/lab11-wordpress-on-linux.md new file mode 100644 index 0000000..eea8afd --- /dev/null +++ b/sysadmin-i-sys255/lab11-wordpress-on-linux.md @@ -0,0 +1,73 @@ +--- +description: >- + In this lab, we installed and configured a WordPress site on the blog01 + machine +--- + +# Lab11 - WordPress on Linux + +{% embed url="https://www.digitalocean.com/community/tutorials/how-to-install-wordpress-on-centos-7" %} + +* connect blog-01 to network (you should be good at this by now) +* remember DNS! +* install [Apache](lab08-apache.md) +* install MySQL + +```bash +curl -sSLO https://dev.mysql.com/get/mysql80-community-release-el7-11.noarch.rpm +sudo rpm -ivh mysql80-community-release-el7-11.noarch.rpm +sudo yum update +sudo yum install mariadb-server +sudo systemctl start mariadb +sudo systemctl status mariadb +sudo mysql_secure_installation +ENTER PASSWORD AND CONFIGS +mysql -u root -p +``` + +* configure WordPress database + +{% code overflow="wrap" fullWidth="false" %} +```bash +CREATE DATABASE wordpress +CREATE USER nathan@localhost IDENTIFIED BY 'password'; +GRANT ALL PRIVILEGES ON wordpress.* TO nathan@localhost IDENTIFIED BY 'password'; +FLUSH PRIVILEGES; +exit +``` +{% endcode %} + +* install PHP + +```bash +yum install http://rpms.remirepo.net/enterprise/remi-release-7.rpm +yum install yum-utils +yum-config-manager --enable remi-php74 +yum update +sudo yum install php php-gd php-mysql +php -v +``` + +* install WordPress + +```bash +sudo service httpd restart +cd ~ +wget http://wordpress.org/latest.tar.gz +tar xzvf latest.tar.gz +sudo rsync -avP ~/wordpress/ /var/www/html/ +sudo chown -R apache:apache /var/www/html/* +``` + +* configure WordPress + +```bash +cd /var/www/html +cp wp-config-sample.php wp-config.php +nano wp-config.php +``` + +
+ +* on WKS, go to http://blog01-nathan/readme.html +* follow the installation steps diff --git a/sysadmin-i-sys255/lab12-automation.md b/sysadmin-i-sys255/lab12-automation.md new file mode 100644 index 0000000..cf7e3c5 --- /dev/null +++ b/sysadmin-i-sys255/lab12-automation.md @@ -0,0 +1,84 @@ +--- +description: >- + In this lab, we set up the clone machines, configured SSH to use RSA keys as + authentication, and used PSSH and Ansible to automate commands +--- + +# Lab12 - Automation + +## Configure clone1, clone2, and clone3 + +For all three machines... + +* Change network adapter to LAN +* `nmtui` + * Manual IP address + * 10.0.5.70/24 + * 10.0.5.71/24 + * 10.0.5.72/24 + * Gateway 10.0.5.2 + * DNS 10.0.5.6 & 8.8.8.8 + * Search domain: nathan.local +* `systemctl restart network` +* `user add nathan && passwd nathan` +* `usermod -aG wheel nathan` +* Add DNS records to AD02 + +## Configuring SSH + +### Creating RSA key pair for SSH + +* `ssh-keygen` + * Default location + * enter a passphrase +* `ssh-copy-id nathan@clone2` +* `ssh-copy-id nathan@clone3` + +
+ +### Add passwordless SSH login (for 1 hour) + +* `` eval `ssh-agent` `` +* `ssh-add -t 1h` +* This is not permanent, you have to retype these commands every session + +### Allow passwordless elevation to root by wheel group members + +* On clone2 and clone3, uncomment this line in /etc/sudoers + +
+ +## PSSH - Parallel SSH. + +* Allows you to run SSH commands on multiple hosts +* On clone1 + + * `yum install epel-release` + * `yum install pssh` + * create a text file called _ssh-hosts.txt_ and add IP addresses of clone2 and clone3 + +
+ + * make sure passwordless SSH is enabled + * `pssh -i -h ssh-hosts.txt -- ` + * `-i` - interactive - show command output + +
+ +## install Ansible + +* On clone1 + + * `sudo yum install ansible` + * `ansible all -i ssh-hosts.txt -m ping` + +
+ + * `-b` - tells Ansible that the user associated with the SSH public key at the other end of the connection is a sudoer user + +
+ + + + + diff --git a/sysadmin-i-sys255/lab13-wordpress-on-windows.md b/sysadmin-i-sys255/lab13-wordpress-on-windows.md new file mode 100644 index 0000000..1dda70a --- /dev/null +++ b/sysadmin-i-sys255/lab13-wordpress-on-windows.md @@ -0,0 +1,105 @@ +--- +description: >- + In this lab, we installed and configured a WordPress site on a Windows 2019 + server +--- + +# Lab13 - WordPress on Windows + +### MySQL + +* go to https://dev.mysql/downloads/installer +* download the MSI file and run it + * Full version, server mode, keep the rest defaults +* MySQL Workbench -> open the only connection + +
+ +* Create a new scheme (database icon) + +
+ +* Add all privileges to root + +
+ +### PHP + +* go to https://windows.php.net/download +* download the non thread safe zip + +
+ +* extract as `php` into the Program Files folder +* go to Environment Variables and add php to PATH + +
+ +
+ + + +* In the php folder, rename php.ini-production to php.ini +* edit php.ini + * cgi.force\_redirect = 0 + * cgi.fix\_pathinfo = 1 + * fastcgi.impersonate = 1 + * fastcgi.logging = 0 + * extension\_dir = "ext" + * extension=mysqli + * extension=pdo\_mysql + +### Install PHPMyAdmin + +* go to phpmyadmin.net +* download the zip on the top right of the page + +### C++ and URL Rewrite + +* download from Microsoft and run the installer + +### Internet Information Services (IIS) + +* Add Web Server (IIS) feature + +
+ +* no roles needed +* Web Server Roles + + * Custom Logging & Logging Tools + * CGI + * IIS 6 Management Compatibility & IIS Management Scripts and Tools + * ASP.NET 4.7 (latest version) + +
+ + +* Go to http://localhost to check if IIS is running +* Tools -> Internet Information Services (IIS) Manager +* Handler Mappings +* Add Module Mapping... + +
+ +
+ +* IIS Manager -> default documents -> add index.php to top priority +* IIS Manager -> FastCGI Settings -> Environment Variables + +
+ +* IIS Manager -> Application Pools -> Add Application pool... -> name it Wordpress (keep defaults) +* rc Wordpress -> Set Application Pool Defaults -> Application Pool Identity +* Sites -> Default Web Site -> Basic Settings... + +
+ +### Install WordPress!!!! + +* download zip from website +* extract into C:\inetpub\wwwroot +* rename to just wordpress +* copy paste all files to the root wordpress folder, then delete the internal wordpress folder +* rename wp-config-sample.php to wp-config.php +* edit with notepad diff --git a/sysadmin-i-sys255/network_configuration.md b/sysadmin-i-sys255/network_configuration.md new file mode 100644 index 0000000..82ff868 --- /dev/null +++ b/sysadmin-i-sys255/network_configuration.md @@ -0,0 +1,45 @@ +# SYS255 - Network Configuration + +### vSphere + +https://vcenter02.cyber.local\ +Username: charlotte.croce@cyber.local\ +Password: cyber.local password + +### fw01-SYS-255-01-charlotte.croce - PfSense firewall + +IP Address: 10.0.17.104\ +Upstream gateway: 10.0.17.2\ +LAN interface: 10.0.5.2\ +Network Adapter 1: WAN\ +Network Adapter 2: LAN + +### wks01-charlotte - Windows workstation + +IP address: 10.0.5.100\ +Default Gateway: 10.0.5.2\ +DNS: 10.0.5.6 + +### ad01-charlotte - Windows server + +IP Address: 10.0.5.6\ +Gateway: 10.0.5.2\ +DNS 10.0.5.2 + +### dhcp01-charlotte - DHCP server + +IP Address: 10.0.5.4\ +Gateway: 10.0.5.2\ +DNS 10.0.5.6 + +### fs01-charlotte - file server + +IP Address: 10.0.5.8\ +Gateway: 10.0.5.2\ +DNS 10.0.5.6 + +### web01-charlotte - web server + +IP Address: 10.0.5.10\ +Gateway: 10.0.5.2\ +DNS 10.0.5.6 diff --git a/sysadmin-ii-sys265/configs/controller/ansible/ansible.cfg b/sysadmin-ii-sys265/configs/controller/ansible/ansible.cfg new file mode 100644 index 0000000..dd43d2b --- /dev/null +++ b/sysadmin-ii-sys265/configs/controller/ansible/ansible.cfg @@ -0,0 +1,2 @@ +[defaults] +host_key_checking = false diff --git a/sysadmin-ii-sys265/configs/controller/ansible/inventory.txt b/sysadmin-ii-sys265/configs/controller/ansible/inventory.txt new file mode 100644 index 0000000..009ef93 --- /dev/null +++ b/sysadmin-ii-sys265/configs/controller/ansible/inventory.txt @@ -0,0 +1,9 @@ +[apache] +ansible1-charlotte +[webmin] +ansible2-charlotte +[windows] +mgmt01-charlotte +wks01-charlotte +[windows:vars] +ansible_shell_type=powershell diff --git a/sysadmin-ii-sys265/configs/controller/ansible/roles/aidevops-linux.yml b/sysadmin-ii-sys265/configs/controller/ansible/roles/aidevops-linux.yml new file mode 100644 index 0000000..b8c0f36 --- /dev/null +++ b/sysadmin-ii-sys265/configs/controller/ansible/roles/aidevops-linux.yml @@ -0,0 +1,85 @@ +- name: Rocky Linux Security Configuration + hosts: ansible1-charlotte + become: yes + gather_facts: yes + tasks: + # Create security admin group first + - name: Create security admin group + group: + name: secadmin + state: present + tags: fs_perms + + # ============================================================ + # SYSTEM ADMINISTRATION ELEMENT: File System Permissions + # ============================================================ + # Create parent directory first + - name: Create data directory + file: + path: /data + state: directory + mode: '0755' + owner: root + group: root + tags: fs_perms + + - name: Create secure data directory + file: + path: /data/secure + state: directory + mode: '0750' + owner: root + group: secadmin + tags: fs_perms + + - name: Set secure permissions on sensitive files + file: + path: "{{ item.path }}" + mode: "{{ item.mode }}" + owner: "{{ item.owner }}" + group: "{{ item.group }}" + with_items: + - { path: '/etc/passwd', mode: '0644', owner: 'root', group: 'root' } + - { path: '/etc/shadow', mode: '0400', owner: 'root', group: 'root' } + - { path: '/etc/ssh/sshd_config', mode: '0600', owner: 'root', group: 'root' } + tags: fs_perms + + # ============================================================ + # SYSTEM HARDENING ELEMENT: Firewall Configuration + # ============================================================ + - name: Ensure firewalld is installed + dnf: + name: firewalld + state: present + tags: firewall + + - name: Enable and start firewalld + service: + name: firewalld + state: started + enabled: yes + tags: firewall + + - name: Allow necessary services + firewalld: + service: "{{ item }}" + permanent: yes + state: enabled + immediate: yes + with_items: + - ssh + - http + - https + tags: firewall + + - name: Block all other ports + firewalld: + port: "{{ item }}" + permanent: yes + state: disabled + immediate: yes + with_items: + - 21/tcp + - 23/tcp + - 25/tcp + tags: firewall diff --git a/sysadmin-ii-sys265/configs/controller/ansible/roles/aidevops-windows.yml b/sysadmin-ii-sys265/configs/controller/ansible/roles/aidevops-windows.yml new file mode 100644 index 0000000..58b012b --- /dev/null +++ b/sysadmin-ii-sys265/configs/controller/ansible/roles/aidevops-windows.yml @@ -0,0 +1,105 @@ + +- name: Windows Security Configuration + hosts: windows + gather_facts: yes + tasks: + # ============================================================ + # SYSTEM ADMINISTRATION ELEMENT: Shared Folder Management + # ============================================================ + - name: Create secure shared folder + win_file: + path: C:\SecureShare + state: directory + tags: file_mgmt + + - name: Share the secure folder + win_share: + name: SecureData + path: C:\SecureShare + description: "Secure data repository" + list: yes + full: Administrators + read: "Domain Users" + deny: "Everyone" + tags: file_mgmt + + - name: Set NTFS permissions on secure folder + win_acl: + path: C:\SecureShare + user: Administrators + rights: FullControl + type: allow + state: present + inheritance_flags: "ContainerInherit,ObjectInherit" + tags: ntfs_perms + + - name: Add read permissions for authenticated users + win_acl: + path: C:\SecureShare + user: "Authenticated Users" + rights: ReadAndExecute + type: allow + state: present + inheritance_flags: "ContainerInherit,ObjectInherit" + tags: ntfs_perms + + # ============================================================ + # SYSTEM HARDENING ELEMENT: Disable Unnecessary Services + # ============================================================ + - name: Check for service existence + win_shell: Get-Service -Name "{{ item }}" -ErrorAction SilentlyContinue + register: service_check + with_items: + - XblGameSave # Xbox Game Saving Service + - XboxNetApiSvc # Xbox Live Networking Service + - DiagTrack # Connected User Experiences and Telemetry + - dmwappushservice # WAP Push Message Routing Service + failed_when: false + changed_when: false + tags: hardening + + - name: Disable unnecessary services if they exist + win_service: + name: "{{ item.item }}" + state: stopped + start_mode: disabled + with_items: "{{ service_check.results }}" + when: item.rc == 0 + tags: hardening + + - name: Report on services not found + debug: + msg: "Service {{ item.item }} not found on {{ inventory_hostname }}" + with_items: "{{ service_check.results }}" + when: item.rc != 0 + tags: hardening + + # ============================================================ + # AD DS GPO ELEMENT 1: Password Policy + # ============================================================ + - name: Configure password policy + win_security_policy: + section: System Access + key: "{{ item.key }}" + value: "{{ item.value }}" + with_items: + - { key: PasswordComplexity, value: 1 } # Enable password complexity + - { key: MinimumPasswordLength, value: 12 } # 12 character minimum + - { key: PasswordHistorySize, value: 24 } # Remember 24 passwords + when: inventory_hostname in ['wks01-charlotte', 'mgmt01-charlotte'] + tags: gpo_password + + # ============================================================ + # AD DS GPO ELEMENT 2: Account Lockout Policy + # ============================================================ + - name: Configure account lockout policy + win_security_policy: + section: System Access + key: "{{ item.key }}" + value: "{{ item.value }}" + with_items: + - { key: LockoutBadCount, value: 5 } # 5 failed attempts + - { key: ResetLockoutCount, value: 30 } # Reset counter after 30 minutes + - { key: LockoutDuration, value: 30 } # Lock for 30 minutes + when: inventory_hostname in ['wks01-charlotte', 'mgmt01-charlotte'] + tags: gpo_lockout diff --git a/sysadmin-ii-sys265/configs/controller/ansible/roles/apache.yml b/sysadmin-ii-sys265/configs/controller/ansible/roles/apache.yml new file mode 100644 index 0000000..8f6adbf --- /dev/null +++ b/sysadmin-ii-sys265/configs/controller/ansible/roles/apache.yml @@ -0,0 +1,39 @@ +- name: apache sys265 + hosts: apache + become: true # Run all tasks with sudo/root privileges + vars: + install_utilities: false + firewalld_enable: true + ansible_os_family: RedHat + ansible_distribution: CentOS # required because role searches for Rocky config files + roles: + - geerlingguy.apache # apply the apache installation role + + handlers: # will run when a task has notify:name parameter + - name: reload firewall # runs after adding firewall rule + command: firewall-cmd --reload + + tasks: + # open port 443 in firewall for apache web interface + - name: add firewall rule + firewalld: + port: "{{ item }}" + permanent: true + immediate: true + state: enabled + loop: + - 80/tcp + - 443/tcp + notify: reload firewall + + - name: install apache + yum: + name: httpd + state: present # will only install if not already + + - name: enable and start apache service + systemd: + name: httpd + enabled: true + state: started + daemon_reload: yes # reload systemd to recognize new service diff --git a/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/.ansible-lint b/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/.ansible-lint new file mode 100644 index 0000000..acc8255 --- /dev/null +++ b/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/.ansible-lint @@ -0,0 +1,3 @@ +skip_list: + - 'yaml' + - 'role-name' diff --git a/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/.github/FUNDING.yml b/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/.github/FUNDING.yml new file mode 100644 index 0000000..96b4938 --- /dev/null +++ b/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/.github/FUNDING.yml @@ -0,0 +1,4 @@ +# These are supported funding model platforms +--- +github: geerlingguy +patreon: geerlingguy diff --git a/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/.github/workflows/ci.yml b/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/.github/workflows/ci.yml new file mode 100644 index 0000000..55a57ec --- /dev/null +++ b/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/.github/workflows/ci.yml @@ -0,0 +1,67 @@ +--- +name: CI +'on': + pull_request: + push: + branches: + - master + schedule: + - cron: "0 5 * * 0" + +defaults: + run: + working-directory: 'geerlingguy.apache' + +jobs: + + lint: + name: Lint + runs-on: ubuntu-latest + steps: + - name: Check out the codebase. + uses: actions/checkout@v4 + with: + path: 'geerlingguy.apache' + + - name: Set up Python 3. + uses: actions/setup-python@v5 + with: + python-version: '3.x' + + - name: Install test dependencies. + run: pip3 install yamllint + + - name: Lint code. + run: | + yamllint . + + molecule: + name: Molecule + runs-on: ubuntu-latest + strategy: + matrix: + distro: + - rockylinux8 + - ubuntu2004 + - debian10 + + steps: + - name: Check out the codebase. + uses: actions/checkout@v4 + with: + path: 'geerlingguy.apache' + + - name: Set up Python 3. + uses: actions/setup-python@v5 + with: + python-version: '3.x' + + - name: Install test dependencies. + run: pip3 install ansible molecule molecule-plugins[docker] docker + + - name: Run Molecule tests. + run: molecule test + env: + PY_COLORS: '1' + ANSIBLE_FORCE_COLOR: '1' + MOLECULE_DISTRO: ${{ matrix.distro }} diff --git a/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/.github/workflows/release.yml b/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/.github/workflows/release.yml new file mode 100644 index 0000000..6182bc7 --- /dev/null +++ b/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/.github/workflows/release.yml @@ -0,0 +1,40 @@ +--- +# This workflow requires a GALAXY_API_KEY secret present in the GitHub +# repository or organization. +# +# See: https://github.com/marketplace/actions/publish-ansible-role-to-galaxy +# See: https://github.com/ansible/galaxy/issues/46 + +name: Release +'on': + push: + tags: + - '*' + +defaults: + run: + working-directory: 'geerlingguy.apache' + +jobs: + + release: + name: Release + runs-on: ubuntu-latest + steps: + - name: Check out the codebase. + uses: actions/checkout@v4 + with: + path: 'geerlingguy.apache' + + - name: Set up Python 3. + uses: actions/setup-python@v5 + with: + python-version: '3.x' + + - name: Install Ansible. + run: pip3 install ansible-core + + - name: Trigger a new import on Galaxy. + run: >- + ansible-galaxy role import --api-key ${{ secrets.GALAXY_API_KEY }} + $(echo ${{ github.repository }} | cut -d/ -f1) $(echo ${{ github.repository }} | cut -d/ -f2) diff --git a/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/.github/workflows/stale.yml b/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/.github/workflows/stale.yml new file mode 100644 index 0000000..044b7f7 --- /dev/null +++ b/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/.github/workflows/stale.yml @@ -0,0 +1,34 @@ +--- +name: Close inactive issues +'on': + schedule: + - cron: "55 18 * * 1" # semi-random time + +jobs: + close-issues: + runs-on: ubuntu-latest + permissions: + issues: write + pull-requests: write + steps: + - uses: actions/stale@v8 + with: + days-before-stale: 120 + days-before-close: 60 + exempt-issue-labels: bug,pinned,security,planned + exempt-pr-labels: bug,pinned,security,planned + stale-issue-label: "stale" + stale-pr-label: "stale" + stale-issue-message: | + This issue has been marked 'stale' due to lack of recent activity. If there is no further activity, the issue will be closed in another 30 days. Thank you for your contribution! + + Please read [this blog post](https://www.jeffgeerling.com/blog/2020/enabling-stale-issue-bot-on-my-github-repositories) to see the reasons why I mark issues as stale. + close-issue-message: | + This issue has been closed due to inactivity. If you feel this is in error, please reopen the issue or file a new issue with the relevant details. + stale-pr-message: | + This pr has been marked 'stale' due to lack of recent activity. If there is no further activity, the issue will be closed in another 30 days. Thank you for your contribution! + + Please read [this blog post](https://www.jeffgeerling.com/blog/2020/enabling-stale-issue-bot-on-my-github-repositories) to see the reasons why I mark issues as stale. + close-pr-message: | + This pr has been closed due to inactivity. If you feel this is in error, please reopen the issue or file a new issue with the relevant details. + repo-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/.gitignore b/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/.gitignore new file mode 100644 index 0000000..8840c8f --- /dev/null +++ b/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/.gitignore @@ -0,0 +1,5 @@ +*.retry +*/__pycache__ +*.pyc +.cache + diff --git a/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/.yamllint b/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/.yamllint new file mode 100644 index 0000000..6dcebf7 --- /dev/null +++ b/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/.yamllint @@ -0,0 +1,10 @@ +--- +extends: default + +rules: + line-length: + max: 120 + level: warning + +ignore: | + .github/workflows/stale.yml diff --git a/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/LICENSE b/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/LICENSE new file mode 100644 index 0000000..4275cf3 --- /dev/null +++ b/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2017 Jeff Geerling + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/README.md b/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/README.md new file mode 100644 index 0000000..960036e --- /dev/null +++ b/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/README.md @@ -0,0 +1,208 @@ +# Ansible Role: Apache 2.x + +[![CI](https://github.com/geerlingguy/ansible-role-apache/workflows/CI/badge.svg?event=push)](https://github.com/geerlingguy/ansible-role-apache/actions?query=workflow%3ACI) + +An Ansible Role that installs Apache 2.x on RHEL/CentOS, Debian/Ubuntu, SLES and Solaris. + +## Requirements + +If you are using SSL/TLS, you will need to provide your own certificate and key files. You can generate a self-signed certificate with a command like `openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout example.key -out example.crt`. + +If you are using Apache with PHP, I recommend using the `geerlingguy.php` role to install PHP, and you can either use mod_php (by adding the proper package, e.g. `libapache2-mod-php5` for Ubuntu, to `php_packages`), or by also using `geerlingguy.apache-php-fpm` to connect Apache to PHP via FPM. See that role's README for more info. + +## Role Variables + +Available variables are listed below, along with default values (see `defaults/main.yml`): + +```yaml +apache_enablerepo: "" +``` + +The repository to use when installing Apache (only used on RHEL/CentOS systems). If you'd like later versions of Apache than are available in the OS's core repositories, use a repository like EPEL (which can be installed with the `geerlingguy.repo-epel` role). + +```yaml +apache_listen_ip: "*" +apache_listen_port: 80 +apache_listen_port_ssl: 443 +``` + +The IP address and ports on which apache should be listening. Useful if you have another service (like a reverse proxy) listening on port 80 or 443 and need to change the defaults. + +```yaml +apache_create_vhosts: true +apache_vhosts_filename: "vhosts.conf" +apache_vhosts_template: "vhosts.conf.j2" +``` + +If set to true, a vhosts file, managed by this role's variables (see below), will be created and placed in the Apache configuration folder. If set to false, you can place your own vhosts file into Apache's configuration folder and skip the convenient (but more basic) one added by this role. You can also override the template used and set a path to your own template, if you need to further customize the layout of your VirtualHosts. + +```yaml +apache_remove_default_vhost: false +``` + +On Debian/Ubuntu, a default virtualhost is included in Apache's configuration. Set this to `true` to remove that default virtualhost configuration file. + +```yaml +apache_global_vhost_settings: | + DirectoryIndex index.php index.html + # Add other global settings on subsequent lines. +``` + +You can add or override global Apache configuration settings in the role-provided vhosts file (assuming `apache_create_vhosts` is true) using this variable. By default it only sets the DirectoryIndex configuration. + +```yaml +apache_vhosts: + # Additional optional properties: 'serveradmin, serveralias, extra_parameters'. + - servername: "local.dev" + documentroot: "/var/www/html" +``` + +Add a set of properties per virtualhost, including `servername` (required), `documentroot` (required), `allow_override` (optional: defaults to the value of `apache_allow_override`), `options` (optional: defaults to the value of `apache_options`), `serveradmin` (optional), `serveralias` (optional) and `extra_parameters` (optional: you can add whatever additional configuration lines you'd like in here). + +Here's an example using `extra_parameters` to add a RewriteRule to redirect all requests to the `www.` site: + +```yaml +- servername: "www.local.dev" + serveralias: "local.dev" + documentroot: "/var/www/html" + extra_parameters: | + RewriteCond %{HTTP_HOST} !^www\. [NC] + RewriteRule ^(.*)$ http://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L] +``` + +The `|` denotes a multiline scalar block in YAML, so newlines are preserved in the resulting configuration file output. + +```yaml +apache_vhosts_ssl: [] +``` + +No SSL vhosts are configured by default, but you can add them using the same pattern as `apache_vhosts`, with a few additional directives, like the following example: + +```yaml +apache_vhosts_ssl: + - servername: "local.dev" + documentroot: "/var/www/html" + certificate_file: "/home/vagrant/example.crt" + certificate_key_file: "/home/vagrant/example.key" + certificate_chain_file: "/path/to/certificate_chain.crt" + extra_parameters: | + RewriteCond %{HTTP_HOST} !^www\. [NC] + RewriteRule ^(.*)$ http://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L] +``` + +Other SSL directives can be managed with other SSL-related role variables. + +```yaml +apache_ssl_no_log: true +``` + +Whether to print SSL-related task output to the console when running the playbook. + +```yaml +apache_ssl_protocol: "All -SSLv2 -SSLv3" +apache_ssl_cipher_suite: "AES256+EECDH:AES256+EDH" +``` + +The SSL protocols and cipher suites that are used/allowed when clients make secure connections to your server. These are secure/sane defaults, but for maximum security, performand, and/or compatibility, you may need to adjust these settings. + +```yaml +apache_allow_override: "All" +apache_options: "-Indexes +FollowSymLinks" +``` + +The default values for the `AllowOverride` and `Options` directives for the `documentroot` directory of each vhost. A vhost can overwrite these values by specifying `allow_override` or `options`. + +```yaml +apache_mods_enabled: + - rewrite + - ssl +apache_mods_disabled: [] +``` + +Which Apache mods to enable or disable (these will be symlinked into the appropriate location). See the `mods-available` directory inside the apache configuration directory (`/etc/apache2/mods-available` on Debian/Ubuntu) for all the available mods. + +```yaml +apache_packages: + - [platform-specific] +``` + +The list of packages to be installed. This defaults to a set of platform-specific packages for RedHat or Debian-based systems (see `vars/RedHat.yml` and `vars/Debian.yml` for the default values). + +```yaml +apache_state: started +``` + +Set initial Apache daemon state to be enforced when this role is run. This should generally remain `started`, but you can set it to `stopped` if you need to fix the Apache config during a playbook run or otherwise would not like Apache started at the time this role is run. + +```yaml +apache_enabled: yes +``` + +Set the Apache service boot time status. This should generally remain `yes`, but you can set it to `no` if you need to run Ansible while leaving the service disabled. + +```yaml +apache_packages_state: present +``` + +If you have enabled any additional repositories such as _ondrej/apache2_, [geerlingguy.repo-epel](https://github.com/geerlingguy/ansible-role-repo-epel), or [geerlingguy.repo-remi](https://github.com/geerlingguy/ansible-role-repo-remi), you may want an easy way to upgrade versions. You can set this to `latest` (combined with `apache_enablerepo` on RHEL) and can directly upgrade to a different Apache version from a different repo (instead of uninstalling and reinstalling Apache). + +```yaml +apache_ignore_missing_ssl_certificate: true +``` + +If you would like to only create SSL vhosts when the vhost certificate is present (e.g. when using Let’s Encrypt), set `apache_ignore_missing_ssl_certificate` to `false`. When doing this, you might need to run your playbook more than once so all the vhosts are configured (if another part of the playbook generates the SSL certificates). + +## .htaccess-based Basic Authorization + +If you require Basic Auth support, you can add it either through a custom template, or by adding `extra_parameters` to a VirtualHost configuration, like so: + +```yaml + extra_parameters: | + + Require valid-user + AuthType Basic + AuthName "Please authenticate" + AuthUserFile /var/www/password-protected-directory/.htpasswd + +``` + +To password protect everything within a VirtualHost directive, use the `Location` block instead of `Directory`: + +``` + + Require valid-user + .... + +``` + +You would need to generate/upload your own `.htpasswd` file in your own playbook. There may be other roles that support this functionality in a more integrated way. + +## Dependencies + +None. + +## Example Playbook + +```yaml +- hosts: webservers + vars_files: + - vars/main.yml + roles: + - { role: geerlingguy.apache } +``` + +*Inside `vars/main.yml`*: + +```yaml +apache_listen_port: 8080 +apache_vhosts: + - {servername: "example.com", documentroot: "/var/www/vhosts/example_com"} +``` + +## License + +MIT / BSD + +## Author Information + +This role was created in 2014 by [Jeff Geerling](https://www.jeffgeerling.com/), author of [Ansible for DevOps](https://www.ansiblefordevops.com/). diff --git a/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/defaults/main.yml b/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/defaults/main.yml new file mode 100644 index 0000000..c1ecb50 --- /dev/null +++ b/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/defaults/main.yml @@ -0,0 +1,62 @@ +--- +apache_enablerepo: "" + +apache_listen_ip: "*" +apache_listen_port: 80 +apache_listen_port_ssl: 443 + +apache_create_vhosts: true +apache_vhosts_filename: "vhosts.conf" +apache_vhosts_template: "vhosts.conf.j2" + +# On Debian/Ubuntu, a default virtualhost is included in Apache's configuration. +# Set this to `true` to remove that default. +apache_remove_default_vhost: false + +apache_global_vhost_settings: | + DirectoryIndex index.php index.html + +apache_vhosts: + # Additional properties: + # 'serveradmin, serveralias, allow_override, options, extra_parameters'. + - servername: "local.dev" + documentroot: "/var/www/html" + +apache_allow_override: "All" +apache_options: "-Indexes +FollowSymLinks" + +apache_vhosts_ssl: [] +# Additional properties: +# 'serveradmin, serveralias, allow_override, options, extra_parameters'. +# - servername: "local.dev", +# documentroot: "/var/www/html", +# certificate_file: "/path/to/certificate.crt", +# certificate_key_file: "/path/to/certificate.key", +# # Optional. +# certificate_chain_file: "/path/to/certificate_chain.crt" + +apache_ignore_missing_ssl_certificate: true + +apache_ssl_no_log: true +apache_ssl_protocol: "All -SSLv2 -SSLv3" +apache_ssl_cipher_suite: "AES256+EECDH:AES256+EDH" + +# Only used on Debian/Ubuntu/Redhat. +apache_mods_enabled: + - rewrite + - ssl +apache_mods_disabled: [] + +# Set initial apache state. Recommended values: `started` or `stopped` +apache_state: started + +# Set initial apache service status. Recommended values: `true` or `false` +apache_enabled: true + +# Set apache state when configuration changes are made. Recommended values: +# `restarted` or `reloaded` +apache_restart_state: restarted + +# Apache package state; use `present` to make sure it's installed, or `latest` +# if you want to upgrade or switch versions using a new repo. +apache_packages_state: present diff --git a/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/handlers/main.yml b/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/handlers/main.yml new file mode 100644 index 0000000..53abffb --- /dev/null +++ b/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/handlers/main.yml @@ -0,0 +1,5 @@ +--- +- name: restart apache + service: + name: "{{ apache_service }}" + state: "{{ apache_restart_state }}" diff --git a/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/meta/.galaxy_install_info b/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/meta/.galaxy_install_info new file mode 100644 index 0000000..92db0f0 --- /dev/null +++ b/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/meta/.galaxy_install_info @@ -0,0 +1,2 @@ +install_date: Sun Feb 23 19:19:22 2025 +version: 4.0.0 diff --git a/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/meta/main.yml b/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/meta/main.yml new file mode 100644 index 0000000..07bea91 --- /dev/null +++ b/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/meta/main.yml @@ -0,0 +1,36 @@ +--- +dependencies: [] + +galaxy_info: + role_name: apache + author: geerlingguy + description: Apache 2.x for Linux. + company: "Midwestern Mac, LLC" + license: "license (BSD, MIT)" + min_ansible_version: 2.10 + platforms: + - name: Fedora + versions: + - all + - name: Amazon + versions: + - all + - name: Debian + versions: + - all + - name: Ubuntu + versions: + - trusty + - xenial + - bionic + - name: Solaris + versions: + - 11.3 + galaxy_tags: + - web + - apache + - webserver + - html + - httpd + +allow_duplicates: true diff --git a/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/molecule/default/converge.yml b/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/molecule/default/converge.yml new file mode 100644 index 0000000..416a2b9 --- /dev/null +++ b/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/molecule/default/converge.yml @@ -0,0 +1,21 @@ +--- +- name: Converge + hosts: all + become: true + + vars: + apache_listen_port_ssl: 443 + apache_create_vhosts: true + apache_vhosts_filename: "vhosts.conf" + apache_vhosts: + - servername: "example.com" + documentroot: "/var/www/vhosts/example_com" + + pre_tasks: + - name: Update apt cache. + apt: update_cache=yes cache_valid_time=600 + when: ansible_os_family == 'Debian' + changed_when: false + + roles: + - role: geerlingguy.apache diff --git a/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/molecule/default/molecule.yml b/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/molecule/default/molecule.yml new file mode 100644 index 0000000..147da5d --- /dev/null +++ b/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/molecule/default/molecule.yml @@ -0,0 +1,21 @@ +--- +role_name_check: 1 +dependency: + name: galaxy + options: + ignore-errors: true +driver: + name: docker +platforms: + - name: instance + image: "geerlingguy/docker-${MOLECULE_DISTRO:-rockylinux8}-ansible:latest" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + cgroupns_mode: host + privileged: true + pre_build_image: true +provisioner: + name: ansible + playbooks: + converge: ${MOLECULE_PLAYBOOK:-converge.yml} diff --git a/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/tasks/configure-Debian.yml b/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/tasks/configure-Debian.yml new file mode 100644 index 0000000..a72bd71 --- /dev/null +++ b/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/tasks/configure-Debian.yml @@ -0,0 +1,59 @@ +--- +- name: Configure Apache. + lineinfile: + dest: "{{ apache_server_root }}/ports.conf" + regexp: "{{ item.regexp }}" + line: "{{ item.line }}" + state: present + mode: 0644 + with_items: "{{ apache_ports_configuration_items }}" + notify: restart apache + +- name: Enable Apache mods. + file: + src: "{{ apache_server_root }}/mods-available/{{ item }}.load" + dest: "{{ apache_server_root }}/mods-enabled/{{ item }}.load" + state: link + mode: 0644 + with_items: "{{ apache_mods_enabled }}" + notify: restart apache + +- name: Disable Apache mods. + file: + path: "{{ apache_server_root }}/mods-enabled/{{ item }}.load" + state: absent + with_items: "{{ apache_mods_disabled }}" + notify: restart apache + +- name: Check whether certificates defined in vhosts exist. + stat: "path={{ item.certificate_file }}" + register: apache_ssl_certificates + with_items: "{{ apache_vhosts_ssl }}" + no_log: "{{ apache_ssl_no_log }}" + +- name: Add apache vhosts configuration. + template: + src: "{{ apache_vhosts_template }}" + dest: "{{ apache_conf_path }}/sites-available/{{ apache_vhosts_filename }}" + owner: root + group: root + mode: 0644 + notify: restart apache + when: apache_create_vhosts | bool + +- name: Add vhost symlink in sites-enabled. + file: + src: "{{ apache_conf_path }}/sites-available/{{ apache_vhosts_filename }}" + dest: "{{ apache_conf_path }}/sites-enabled/{{ apache_vhosts_filename }}" + state: link + mode: 0644 + force: "{{ ansible_check_mode }}" + notify: restart apache + when: apache_create_vhosts | bool + +- name: Remove default vhost in sites-enabled. + file: + path: "{{ apache_conf_path }}/sites-enabled/{{ apache_default_vhost_filename }}" + state: absent + notify: restart apache + when: apache_remove_default_vhost diff --git a/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/tasks/configure-RedHat.yml b/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/tasks/configure-RedHat.yml new file mode 100644 index 0000000..6a46980 --- /dev/null +++ b/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/tasks/configure-RedHat.yml @@ -0,0 +1,54 @@ +--- +- name: Configure Apache. + lineinfile: + dest: "{{ apache_server_root }}/conf/{{ apache_daemon }}.conf" + regexp: "{{ item.regexp }}" + line: "{{ item.line }}" + state: present + mode: 0644 + with_items: "{{ apache_ports_configuration_items }}" + notify: restart apache + +- name: Check whether certificates defined in vhosts exist. + stat: path={{ item.certificate_file }} + register: apache_ssl_certificates + with_items: "{{ apache_vhosts_ssl }}" + no_log: "{{ apache_ssl_no_log }}" + +- name: Enable Apache mods. + copy: + dest: "{{ apache_server_root }}/conf.modules.d/99-ansible-{{ item }}.conf" + content: | + LoadModule {{ item }}_module modules/mod_{{ item }}.so + mode: 0644 + with_items: "{{ apache_mods_enabled }}" + notify: restart apache + +- name: Disable Apache mods + file: + path: "{{ apache_server_root }}/conf.modules.d/99-ansible-{{ item }}.conf" + state: absent + with_items: "{{ apache_mods_disabled }}" + notify: restart apache + +- name: Add apache vhosts configuration. + template: + src: "{{ apache_vhosts_template }}" + dest: "{{ apache_conf_path }}/{{ apache_vhosts_filename }}" + owner: root + group: root + mode: 0644 + notify: restart apache + when: apache_create_vhosts | bool + +- name: Check if localhost cert exists (RHEL 8 and later). + stat: + path: /etc/pki/tls/certs/localhost.crt + register: localhost_cert + when: ansible_distribution_major_version | int >= 8 + +- name: Ensure httpd certs are installed (RHEL 8 and later). + command: /usr/libexec/httpd-ssl-gencerts + when: + - ansible_distribution_major_version | int >= 8 + - not localhost_cert.stat.exists diff --git a/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/tasks/configure-Solaris.yml b/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/tasks/configure-Solaris.yml new file mode 100644 index 0000000..2fbf832 --- /dev/null +++ b/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/tasks/configure-Solaris.yml @@ -0,0 +1,20 @@ +--- +- name: Configure Apache. + lineinfile: + dest: "{{ apache_server_root }}/{{ apache_daemon }}.conf" + regexp: "{{ item.regexp }}" + line: "{{ item.line }}" + state: present + mode: 0644 + with_items: "{{ apache_ports_configuration_items }}" + notify: restart apache + +- name: Add apache vhosts configuration. + template: + src: "{{ apache_vhosts_template }}" + dest: "{{ apache_conf_path }}/{{ apache_vhosts_filename }}" + owner: root + group: root + mode: 0644 + notify: restart apache + when: apache_create_vhosts | bool diff --git a/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/tasks/configure-Suse.yml b/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/tasks/configure-Suse.yml new file mode 100644 index 0000000..9d21ee4 --- /dev/null +++ b/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/tasks/configure-Suse.yml @@ -0,0 +1,26 @@ +--- +- name: Configure Apache. + lineinfile: + dest: "{{ apache_server_root }}/listen.conf" + regexp: "{{ item.regexp }}" + line: "{{ item.line }}" + state: present + mode: 0644 + with_items: "{{ apache_ports_configuration_items }}" + notify: restart apache + +- name: Check whether certificates defined in vhosts exist. + stat: path={{ item.certificate_file }} + register: apache_ssl_certificates + with_items: "{{ apache_vhosts_ssl }}" + no_log: "{{ apache_ssl_no_log }}" + +- name: Add apache vhosts configuration. + template: + src: "{{ apache_vhosts_template }}" + dest: "{{ apache_conf_path }}/{{ apache_vhosts_filename }}" + owner: root + group: root + mode: 0644 + notify: restart apache + when: apache_create_vhosts | bool diff --git a/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/tasks/main.yml b/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/tasks/main.yml new file mode 100644 index 0000000..567356c --- /dev/null +++ b/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/tasks/main.yml @@ -0,0 +1,47 @@ +--- +# Include variables and define needed variables. +- name: Include OS-specific variables. + include_vars: "{{ ansible_os_family }}.yml" + +- name: Include variables for Amazon Linux. + include_vars: "AmazonLinux.yml" + when: + - ansible_distribution == "Amazon" + - ansible_distribution_major_version == "NA" + +- name: Define apache_packages. + set_fact: + apache_packages: "{{ __apache_packages | list }}" + when: apache_packages is not defined + +# Setup/install tasks. +- include_tasks: "setup-{{ ansible_os_family }}.yml" + +# Figure out what version of Apache is installed. +- name: Get installed version of Apache. + command: "{{ apache_daemon_path }}{{ apache_daemon }} -v" + changed_when: false + check_mode: false + register: _apache_version + +- name: Create apache_version variable. + set_fact: + apache_version: "{{ _apache_version.stdout.split()[2].split('/')[1] }}" + +- name: Include Apache 2.2 variables. + include_vars: apache-22.yml + when: "apache_version.split('.')[1] == '2'" + +- name: Include Apache 2.4 variables. + include_vars: apache-24.yml + when: "apache_version.split('.')[1] == '4'" + +# Configure Apache. +- name: Configure Apache. + include_tasks: "configure-{{ ansible_os_family }}.yml" + +- name: Ensure Apache has selected state and enabled on boot. + service: + name: "{{ apache_service }}" + state: "{{ apache_state }}" + enabled: "{{ apache_enabled }}" diff --git a/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/tasks/setup-Debian.yml b/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/tasks/setup-Debian.yml new file mode 100644 index 0000000..b5d1412 --- /dev/null +++ b/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/tasks/setup-Debian.yml @@ -0,0 +1,6 @@ +--- +- name: Update apt cache. + apt: update_cache=yes cache_valid_time=3600 + +- name: Ensure Apache is installed on Debian. + apt: "name={{ apache_packages }} state={{ apache_packages_state }}" diff --git a/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/tasks/setup-RedHat.yml b/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/tasks/setup-RedHat.yml new file mode 100644 index 0000000..dfc9016 --- /dev/null +++ b/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/tasks/setup-RedHat.yml @@ -0,0 +1,6 @@ +--- +- name: Ensure Apache is installed on RHEL. + package: + name: "{{ apache_packages }}" + state: "{{ apache_packages_state }}" + enablerepo: "{{ apache_enablerepo | default(omit, true) }}" diff --git a/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/tasks/setup-Solaris.yml b/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/tasks/setup-Solaris.yml new file mode 100644 index 0000000..a4ae450 --- /dev/null +++ b/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/tasks/setup-Solaris.yml @@ -0,0 +1,5 @@ +--- +- name: Ensure Apache is installed on Solaris. + pkg5: + name: "{{ apache_packages }}" + state: "{{ apache_packages_state }}" diff --git a/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/tasks/setup-Suse.yml b/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/tasks/setup-Suse.yml new file mode 100644 index 0000000..725266b --- /dev/null +++ b/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/tasks/setup-Suse.yml @@ -0,0 +1,5 @@ +--- +- name: Ensure Apache is installed on Suse. + zypper: + name: "{{ apache_packages }}" + state: "{{ apache_packages_state }}" diff --git a/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/templates/vhosts.conf.j2 b/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/templates/vhosts.conf.j2 new file mode 100644 index 0000000..b5307b9 --- /dev/null +++ b/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/templates/vhosts.conf.j2 @@ -0,0 +1,82 @@ +{{ apache_global_vhost_settings }} + +{# Set up VirtualHosts #} +{% for vhost in apache_vhosts %} + + ServerName {{ vhost.servername }} +{% if vhost.serveralias is defined %} + ServerAlias {{ vhost.serveralias }} +{% endif %} +{% if vhost.documentroot is defined %} + DocumentRoot "{{ vhost.documentroot }}" +{% endif %} + +{% if vhost.serveradmin is defined %} + ServerAdmin {{ vhost.serveradmin }} +{% endif %} +{% if vhost.documentroot is defined %} + + AllowOverride {{ vhost.allow_override | default(apache_allow_override) }} + Options {{ vhost.options | default(apache_options) }} +{% if apache_vhosts_version == "2.2" %} + Order allow,deny + Allow from all +{% else %} + Require all granted +{% endif %} + +{% endif %} +{% if vhost.extra_parameters is defined %} +{{ vhost.extra_parameters | indent(width=2, first=True) }} +{% endif %} + + +{% endfor %} + +{# Set up SSL VirtualHosts #} +{% for vhost in apache_vhosts_ssl %} +{% if apache_ignore_missing_ssl_certificate or apache_ssl_certificates.results[loop.index0].stat.exists %} + + ServerName {{ vhost.servername }} +{% if vhost.serveralias is defined %} + ServerAlias {{ vhost.serveralias }} +{% endif %} +{% if vhost.documentroot is defined %} + DocumentRoot "{{ vhost.documentroot }}" +{% endif %} + + SSLEngine on + SSLCipherSuite {{ apache_ssl_cipher_suite }} + SSLProtocol {{ apache_ssl_protocol }} + SSLHonorCipherOrder On +{% if apache_vhosts_version == "2.4" %} + SSLCompression off +{% endif %} + SSLCertificateFile {{ vhost.certificate_file }} + SSLCertificateKeyFile {{ vhost.certificate_key_file }} +{% if vhost.certificate_chain_file is defined %} + SSLCertificateChainFile {{ vhost.certificate_chain_file }} +{% endif %} + +{% if vhost.serveradmin is defined %} + ServerAdmin {{ vhost.serveradmin }} +{% endif %} +{% if vhost.documentroot is defined %} + + AllowOverride {{ vhost.allow_override | default(apache_allow_override) }} + Options {{ vhost.options | default(apache_options) }} +{% if apache_vhosts_version == "2.2" %} + Order allow,deny + Allow from all +{% else %} + Require all granted +{% endif %} + +{% endif %} +{% if vhost.extra_parameters is defined %} +{{ vhost.extra_parameters | indent(width=2, first=True) }} +{% endif %} + + +{% endif %} +{% endfor %} diff --git a/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/vars/AmazonLinux.yml b/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/vars/AmazonLinux.yml new file mode 100644 index 0000000..165f65d --- /dev/null +++ b/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/vars/AmazonLinux.yml @@ -0,0 +1,18 @@ +--- +apache_service: httpd +apache_daemon: httpd +apache_daemon_path: /usr/sbin/ +apache_server_root: /etc/httpd +apache_conf_path: /etc/httpd/conf.d + +apache_vhosts_version: "2.4" + +__apache_packages: + - httpd24 + - httpd24-devel + - mod24_ssl + - openssh + +apache_ports_configuration_items: + - regexp: "^Listen " + line: "Listen {{ apache_listen_port }}" diff --git a/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/vars/Debian.yml b/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/vars/Debian.yml new file mode 100644 index 0000000..7ff09c5 --- /dev/null +++ b/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/vars/Debian.yml @@ -0,0 +1,14 @@ +--- +apache_service: apache2 +apache_daemon: apache2 +apache_daemon_path: /usr/sbin/ +apache_server_root: /etc/apache2 +apache_conf_path: /etc/apache2 + +__apache_packages: + - apache2 + - apache2-utils + +apache_ports_configuration_items: + - regexp: "^Listen " + line: "Listen {{ apache_listen_port }}" diff --git a/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/vars/RedHat.yml b/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/vars/RedHat.yml new file mode 100644 index 0000000..d79fa5a --- /dev/null +++ b/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/vars/RedHat.yml @@ -0,0 +1,20 @@ +--- +apache_service: httpd +apache_daemon: httpd +apache_daemon_path: /usr/sbin/ +apache_server_root: /etc/httpd +apache_conf_path: /etc/httpd/conf.d + +apache_vhosts_version: "2.2" + +__apache_packages: + - httpd + - httpd-devel + - mod_ssl + - openssh + +apache_ports_configuration_items: + - regexp: "^Listen " + line: "Listen {{ apache_listen_port }}" + - regexp: "^#?NameVirtualHost " + line: "NameVirtualHost {{ apache_listen_ip }}:{{ apache_listen_port }}" diff --git a/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/vars/Solaris.yml b/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/vars/Solaris.yml new file mode 100644 index 0000000..576291e --- /dev/null +++ b/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/vars/Solaris.yml @@ -0,0 +1,19 @@ +--- +apache_service: apache24 +apache_daemon: httpd +apache_daemon_path: /usr/apache2/2.4/bin/ +apache_server_root: /etc/apache2/2.4/ +apache_conf_path: /etc/apache2/2.4/conf.d + +apache_vhosts_version: "2.2" + +__apache_packages: + - web/server/apache-24 + - web/server/apache-24/module/apache-ssl + - web/server/apache-24/module/apache-security + +apache_ports_configuration_items: + - regexp: "^Listen " + line: "Listen {{ apache_listen_port }}" + - regexp: "^#?NameVirtualHost " + line: "NameVirtualHost {{ apache_listen_ip }}:{{ apache_listen_port }}" diff --git a/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/vars/Suse.yml b/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/vars/Suse.yml new file mode 100644 index 0000000..27703f3 --- /dev/null +++ b/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/vars/Suse.yml @@ -0,0 +1,18 @@ +--- +apache_service: apache2 +apache_daemon: httpd2 +apache_daemon_path: /usr/sbin/ +apache_server_root: /etc/apache2 +apache_conf_path: /etc/apache2/conf.d + +apache_vhosts_version: "2.2" + +__apache_packages: + - apache2 + - openssh + +apache_ports_configuration_items: + - regexp: "^Listen " + line: "Listen {{ apache_listen_port }}" + - regexp: "^#?NameVirtualHost " + line: "NameVirtualHost {{ apache_listen_ip }}:{{ apache_listen_port }}" diff --git a/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/vars/apache-22.yml b/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/vars/apache-22.yml new file mode 100644 index 0000000..c932f93 --- /dev/null +++ b/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/vars/apache-22.yml @@ -0,0 +1,12 @@ +--- +apache_vhosts_version: "2.2" +apache_default_vhost_filename: 000-default +apache_ports_configuration_items: + - { + regexp: "^Listen ", + line: "Listen {{ apache_listen_port }}" + } + - { + regexp: "^#?NameVirtualHost ", + line: "NameVirtualHost {{ apache_listen_ip }}:{{ apache_listen_port }}" + } diff --git a/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/vars/apache-24.yml b/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/vars/apache-24.yml new file mode 100644 index 0000000..cdd66e5 --- /dev/null +++ b/sysadmin-ii-sys265/configs/controller/ansible/roles/geerlingguy.apache/vars/apache-24.yml @@ -0,0 +1,8 @@ +--- +apache_vhosts_version: "2.4" +apache_default_vhost_filename: 000-default.conf +apache_ports_configuration_items: + - { + regexp: "^Listen ", + line: "Listen {{ (apache_listen_ip == '*') | ternary('', apache_listen_ip + ':') }}{{ apache_listen_port }}" + } diff --git a/sysadmin-ii-sys265/configs/controller/ansible/roles/semuadmin.webmin/.gitignore b/sysadmin-ii-sys265/configs/controller/ansible/roles/semuadmin.webmin/.gitignore new file mode 100644 index 0000000..1cbf1bf --- /dev/null +++ b/sysadmin-ii-sys265/configs/controller/ansible/roles/semuadmin.webmin/.gitignore @@ -0,0 +1,2 @@ +.DS_Store +.dropbox diff --git a/sysadmin-ii-sys265/configs/controller/ansible/roles/semuadmin.webmin/LICENSE b/sysadmin-ii-sys265/configs/controller/ansible/roles/semuadmin.webmin/LICENSE new file mode 100644 index 0000000..7f96bbe --- /dev/null +++ b/sysadmin-ii-sys265/configs/controller/ansible/roles/semuadmin.webmin/LICENSE @@ -0,0 +1,26 @@ +BSD 3-Clause License ("BSD License 2.0", "Revised BSD License", "New BSD License", or "Modified BSD License") + +Copyright (c) 2019, SEMU Consulting +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/sysadmin-ii-sys265/configs/controller/ansible/roles/semuadmin.webmin/README.md b/sysadmin-ii-sys265/configs/controller/ansible/roles/semuadmin.webmin/README.md new file mode 100644 index 0000000..cf37091 --- /dev/null +++ b/sysadmin-ii-sys265/configs/controller/ansible/roles/semuadmin.webmin/README.md @@ -0,0 +1,66 @@ +Role Name +========= + +## THIS REPO IS NO LONGER BEING ACTIVELY MAINTAINED OR SUPPORTED. + +### IF ANYONE ELSE WANTS TO TAKE ON THE MAINTENANCE AND SUPPORT, FEEL FREE TO FORK IT. + +[Ansible role](https://galaxy.ansible.com/semuadmin/webmin) to deploy Webmin web-based linux administration utility, running as a +systemd service. + +Webmin service will be available on https://hostip:10000. + +Default login will be the userid and password of the installer user. + +You may get a browser warning about Webmin's default self-sign SSL certificate. + +System will reboot after installation. + + +Requirements +------------ + +- Installation requires sudo privileges. +- Systemd for services control. +- Firewalld for firewall control (if required). +- Python for Ansible provisioning (note that some minimal distributions do not include python out of the box). + +Role Variables +-------------- + +- `install_utilities`: false. Set to True to install various utility packages used by Webmin management functions (wget, git, ntpdate, sntp, smartmontools). +Note that some minimal distributions do not support all these tools out of the box and may require interactive installation. + +- `enable_firewalld`: false. Set to True to open port 10000 via firewalld (assumes firewalld is installed and running). + +- `uninstall_webmin` : false. Set to true to uninstall Webmin. + +Dependencies +------------ + +None. + +Example Playbook +---------------- + +Including an example of how to use your role (for instance, with variables passed in as parameters) is always nice for users too: + +```yaml + + - name: Provision webmin role + hosts: all + become: true + become_user: root + + vars: + enable_firewalld: true + install_utilities: true + + roles: + - semuadmin.webmin +``` + +License +------- + +BSD 3-Clause diff --git a/sysadmin-ii-sys265/configs/controller/ansible/roles/semuadmin.webmin/defaults/main.yml b/sysadmin-ii-sys265/configs/controller/ansible/roles/semuadmin.webmin/defaults/main.yml new file mode 100644 index 0000000..c48e039 --- /dev/null +++ b/sysadmin-ii-sys265/configs/controller/ansible/roles/semuadmin.webmin/defaults/main.yml @@ -0,0 +1,15 @@ +--- +# defaults file for webmin + +webmin_dir: /etc/webmin +webmin_yum_repo: "http://download.webmin.com/download/yum" +webmin_mirrorlist: "http://download.webmin.com/download/yum/mirrorlist" +webmin_gpgkey: "http://www.webmin.com/jcameron-key.asc" + +webmin_apt_repo: "deb [signed-by=/etc/apt/trusted.gpg.d/jcameron-key.asc] https://download.webmin.com/download/repository sarge contrib" + +enable_firewalld: false +install_utilities: false +uninstall_webmin: false + +webmin_disable_reboot: false diff --git a/sysadmin-ii-sys265/configs/controller/ansible/roles/semuadmin.webmin/handlers/main.yml b/sysadmin-ii-sys265/configs/controller/ansible/roles/semuadmin.webmin/handlers/main.yml new file mode 100644 index 0000000..f1225e8 --- /dev/null +++ b/sysadmin-ii-sys265/configs/controller/ansible/roles/semuadmin.webmin/handlers/main.yml @@ -0,0 +1,7 @@ +--- +# handlers file for webmin + +- name: Restart webmin + ansible.builtin.systemd: + name: webmin + state: restarted diff --git a/sysadmin-ii-sys265/configs/controller/ansible/roles/semuadmin.webmin/meta/.galaxy_install_info b/sysadmin-ii-sys265/configs/controller/ansible/roles/semuadmin.webmin/meta/.galaxy_install_info new file mode 100644 index 0000000..e3f4f56 --- /dev/null +++ b/sysadmin-ii-sys265/configs/controller/ansible/roles/semuadmin.webmin/meta/.galaxy_install_info @@ -0,0 +1,2 @@ +install_date: Sat Feb 22 17:36:07 2025 +version: v1.0.9 diff --git a/sysadmin-ii-sys265/configs/controller/ansible/roles/semuadmin.webmin/meta/main.yml b/sysadmin-ii-sys265/configs/controller/ansible/roles/semuadmin.webmin/meta/main.yml new file mode 100644 index 0000000..e0905bc --- /dev/null +++ b/sysadmin-ii-sys265/configs/controller/ansible/roles/semuadmin.webmin/meta/main.yml @@ -0,0 +1,29 @@ +galaxy_info: + role_name: webmin + author: semu + description: webmin role + company: SEMU Consulting + + license: BSD 3-Clause + + min_ansible_version: "7" + + platforms: + - name: EL + versions: + - "9" + - "8" + - "7" + - name: Fedora + versions: + - "36" + - name: Debian + versions: + - bullseye + - name: Ubuntu + versions: + - focal + - bionic + - jammy + galaxy_tags: + - webmin diff --git a/sysadmin-ii-sys265/configs/controller/ansible/roles/semuadmin.webmin/tasks/main.yml b/sysadmin-ii-sys265/configs/controller/ansible/roles/semuadmin.webmin/tasks/main.yml new file mode 100644 index 0000000..66028e5 --- /dev/null +++ b/sysadmin-ii-sys265/configs/controller/ansible/roles/semuadmin.webmin/tasks/main.yml @@ -0,0 +1,10 @@ +--- +# tasks file for webmin # + +- name: Install webmin + ansible.builtin.include_tasks: webmin.yml + when: not uninstall_webmin + +- name: Uninstall webmin + ansible.builtin.include_tasks: uninstall.yml + when: uninstall_webmin diff --git a/sysadmin-ii-sys265/configs/controller/ansible/roles/semuadmin.webmin/tasks/uninstall.yml b/sysadmin-ii-sys265/configs/controller/ansible/roles/semuadmin.webmin/tasks/uninstall.yml new file mode 100644 index 0000000..707168a --- /dev/null +++ b/sysadmin-ii-sys265/configs/controller/ansible/roles/semuadmin.webmin/tasks/uninstall.yml @@ -0,0 +1,42 @@ +--- +# tasks file for uninstall webmin # + +- name: Remove Webmin files and directories + ansible.builtin.file: + path: "/etc/webmin" + state: absent + +- name: Disable firewalld service. + ansible.posix.firewalld: + zone: public + service: webmin + permanent: true + state: disabled + immediate: true + when: enable_firewalld + +- name: Remove yum repository for Redhat platforms + ansible.builtin.yum_repository: + name: webmin + description: Webmin yum repo + baseurl: "{{ webmin_yum_repo }}" + mirrorlist: "{{ webmin_mirrorlist }}" + state: absent + when: ansible_os_family == "RedHat" + +- name: Remove apt repository for Debian platforms + ansible.builtin.apt_repository: + repo: "{{ webmin_apt_repo }}" + state: absent + when: ansible_os_family == "Debian" + +- name: Unnstall supporting packages if added + ansible.builtin.package: + name: + - wget + - git + - ntpdate + - sntp + - smartmontools + state: absent + when: install_utilities diff --git a/sysadmin-ii-sys265/configs/controller/ansible/roles/semuadmin.webmin/tasks/webmin.yml b/sysadmin-ii-sys265/configs/controller/ansible/roles/semuadmin.webmin/tasks/webmin.yml new file mode 100644 index 0000000..03b1600 --- /dev/null +++ b/sysadmin-ii-sys265/configs/controller/ansible/roles/semuadmin.webmin/tasks/webmin.yml @@ -0,0 +1,94 @@ +--- +# tasks file for webmin# + +- name: Install firewalld service template. + ansible.builtin.template: + src: webmin.xml.j2 + dest: "/etc/firewalld/services/webmin.xml" + owner: root + group: root + mode: "0644" + when: enable_firewalld + +- name: Reload firewalld to register new service. + ansible.builtin.command: firewall-cmd --reload + register: firewall + changed_when: "'success' in firewall.stdout" + when: enable_firewalld + +- name: Enable firewalld service. + ansible.posix.firewalld: + zone: public + service: webmin + permanent: true + state: enabled + immediate: true + when: enable_firewalld + +- name: Add yum repository and gpg key for Redhat platforms. + ansible.builtin.yum_repository: + name: webmin + description: Webmin yum repo + baseurl: "{{ webmin_yum_repo }}" + mirrorlist: "{{ webmin_mirrorlist }}" + gpgkey: "{{ webmin_gpgkey }}" + gpgcheck: true + state: present + when: ansible_os_family == "RedHat" + +- name: Add a gpg key for Debian platforms. + ansible.builtin.get_url: + url: "{{ webmin_gpgkey }}" + dest: /etc/apt/trusted.gpg.d/jcameron-key.asc + owner: root + group: root + mode: "0644" + when: ansible_os_family == "Debian" + +- name: Add apt repository for Debian platforms. + ansible.builtin.apt_repository: + repo: "{{ webmin_apt_repo }}" + state: present + update_cache: true + when: ansible_os_family == "Debian" + +- name: Install https transport for Debian platforms. + ansible.builtin.package: + name: + - apt-transport-https + state: present + when: ansible_os_family == "Debian" + +- name: Install Webmin. + ansible.builtin.package: + name: + - webmin + state: present + +- name: Install supporting packages if required. + ansible.builtin.package: + name: + - wget + - git + - ntpdate + - sntp + - smartmontools + state: present + when: install_utilities + +- name: Remove old systemd service. + ansible.builtin.file: + path: /etc/systemd/system/webmin.service + state: absent + +- name: Enable webmin as systemd service. + ansible.builtin.systemd: + state: started + enabled: true + daemon_reload: true + name: webmin + +- name: Reboot machine. + ansible.builtin.reboot: + reboot_timeout: 3600 + when: not webmin_disable_reboot diff --git a/sysadmin-ii-sys265/configs/controller/ansible/roles/semuadmin.webmin/templates/webmin.xml.j2 b/sysadmin-ii-sys265/configs/controller/ansible/roles/semuadmin.webmin/templates/webmin.xml.j2 new file mode 100644 index 0000000..8502404 --- /dev/null +++ b/sysadmin-ii-sys265/configs/controller/ansible/roles/semuadmin.webmin/templates/webmin.xml.j2 @@ -0,0 +1,6 @@ + + + webmin + Webmin Web Based Administration + + \ No newline at end of file diff --git a/sysadmin-ii-sys265/configs/controller/ansible/roles/semuadmin.webmin/tests/inventory b/sysadmin-ii-sys265/configs/controller/ansible/roles/semuadmin.webmin/tests/inventory new file mode 100644 index 0000000..878877b --- /dev/null +++ b/sysadmin-ii-sys265/configs/controller/ansible/roles/semuadmin.webmin/tests/inventory @@ -0,0 +1,2 @@ +localhost + diff --git a/sysadmin-ii-sys265/configs/controller/ansible/roles/semuadmin.webmin/tests/test.yml b/sysadmin-ii-sys265/configs/controller/ansible/roles/semuadmin.webmin/tests/test.yml new file mode 100644 index 0000000..4117367 --- /dev/null +++ b/sysadmin-ii-sys265/configs/controller/ansible/roles/semuadmin.webmin/tests/test.yml @@ -0,0 +1,6 @@ +--- +- name: Test webmin role + hosts: localhost + remote_user: root + roles: + - webmin diff --git a/sysadmin-ii-sys265/configs/controller/ansible/roles/semuadmin.webmin/vars/main.yml b/sysadmin-ii-sys265/configs/controller/ansible/roles/semuadmin.webmin/vars/main.yml new file mode 100644 index 0000000..276539a --- /dev/null +++ b/sysadmin-ii-sys265/configs/controller/ansible/roles/semuadmin.webmin/vars/main.yml @@ -0,0 +1,2 @@ +--- +# vars file for webmin diff --git a/sysadmin-ii-sys265/configs/controller/ansible/roles/webmin.yml b/sysadmin-ii-sys265/configs/controller/ansible/roles/webmin.yml new file mode 100644 index 0000000..7b9244f --- /dev/null +++ b/sysadmin-ii-sys265/configs/controller/ansible/roles/webmin.yml @@ -0,0 +1,49 @@ + +- name: webmin sys265 + hosts: webmin + become: true + vars: + install_utilities: false + firewalld_enable: true + + pre_tasks: + - name: add webmin repo and GPG key + yum_repository: + name: webmin + description: Webmin Distribution Neutral + baseurl: http://download.webmin.com/download/yum + enabled: true + gpgcheck: true + gpgkey: http://www.webmin.com/jcameron-key.asc + + - name: clean and update YUM cache + yum: + update_cache: yes + + roles: + - semuadmin.webmin + + handlers: + - name: reload firewall + command: firewall-cmd --reload + + tasks: + - name: add firewall rule + firewalld: + port: 10000/tcp + permanent: true + state: enabled + notify: reload firewall + + - name: install webmin + yum: + name: webmin + state: present + + - name: enable and start webmin service + systemd: + name: webmin + enabled: true + state: started + daemon_reload: yes + diff --git a/sysadmin-ii-sys265/configs/controller/ansible/roles/windows_software.yml b/sysadmin-ii-sys265/configs/controller/ansible/roles/windows_software.yml new file mode 100644 index 0000000..e8cd2c1 --- /dev/null +++ b/sysadmin-ii-sys265/configs/controller/ansible/roles/windows_software.yml @@ -0,0 +1,10 @@ +- name: install windows applications + hosts: windows + tasks: + - name: install firefox and 7zip + win_chocolatey: + name: + - firefox + - 7zip + - notepadplusplus + state: present diff --git a/sysadmin-ii-sys265/configs/docker-01/00-installer-config.yaml b/sysadmin-ii-sys265/configs/docker-01/00-installer-config.yaml new file mode 100644 index 0000000..55479ad --- /dev/null +++ b/sysadmin-ii-sys265/configs/docker-01/00-installer-config.yaml @@ -0,0 +1,14 @@ +# This is the network config written by 'subiquity' +network: + ethernets: + ens160: + dhcp4: no + addresses: + - 10.0.5.12/24 + routes: + - to: default + via: 10.0.5.2 + nameservers: + addresses: + - 10.0.5.5 + version: 2 diff --git a/sysadmin-ii-sys265/configs/docker-01/README.md b/sysadmin-ii-sys265/configs/docker-01/README.md new file mode 100644 index 0000000..0ddb7c7 --- /dev/null +++ b/sysadmin-ii-sys265/configs/docker-01/README.md @@ -0,0 +1 @@ +docker-01 configuration diff --git a/sysadmin-ii-sys265/configs/docker-01/cloud.cfg b/sysadmin-ii-sys265/configs/docker-01/cloud.cfg new file mode 100644 index 0000000..d9e258e --- /dev/null +++ b/sysadmin-ii-sys265/configs/docker-01/cloud.cfg @@ -0,0 +1,142 @@ +# The top level settings are used as module +# and system configuration. +# A set of users which may be applied and/or used by various modules +# when a 'default' entry is found it will reference the 'default_user' +# from the distro configuration specified below +users: + - default + + +# If this is set, 'root' will not be able to ssh in and they +# will get a message to login instead as the default $user +disable_root: true + +# This will cause the set+update hostname module to not operate (if true) +preserve_hostname: true +hostname: docker01-charlotte +fqdn: docker01-charlotte.charlotte.local + +# If you use datasource_list array, keep array items in a single line. +# If you use multi line array, ds-identify script won't read array items. +# Example datasource config +# datasource: +# Ec2: +# metadata_urls: [ 'blah.com' ] +# timeout: 5 # (defaults to 50 seconds) +# max_wait: 10 # (defaults to 120 seconds) + + + +# The modules that run in the 'init' stage +cloud_init_modules: + - migrator + - seed_random + - bootcmd + - write-files + - growpart + - resizefs + - disk_setup + - mounts + - set_hostname + - update_hostname + - update_etc_hosts + - ca-certs + - rsyslog + - users-groups + - ssh + +# The modules that run in the 'config' stage +cloud_config_modules: +# Emit the cloud config ready event +# this can be used by upstart jobs for 'start on cloud-config'. + - emit_upstart + - snap + - ssh-import-id + - keyboard + - locale + - set-passwords + - grub-dpkg + - apt-pipelining + - apt-configure + - ubuntu-advantage + - ntp + - timezone + - disable-ec2-metadata + - runcmd + - byobu + +# The modules that run in the 'final' stage +cloud_final_modules: + - package-update-upgrade-install + - fan + - landscape + - lxd + - ubuntu-drivers + - write-files-deferred + - puppet + - chef + - mcollective + - salt-minion + - reset_rmc + - refresh_rmc_and_interface + - rightscale_userdata + - scripts-vendor + - scripts-per-once + - scripts-per-boot + - scripts-per-instance + - scripts-user + - ssh-authkey-fingerprints + - keys-to-console + - install-hotplug + - phone-home + - final-message + - power-state-change + +# System and/or distro specific settings +# (not accessible to handlers/transforms) +system_info: + # This will affect which distro class gets used + distro: ubuntu + # Default user name + that default users groups (if added/used) + default_user: + name: ubuntu + lock_passwd: True + gecos: Ubuntu + groups: [adm, audio, cdrom, dialout, dip, floppy, lxd, netdev, plugdev, sudo, video] + sudo: ["ALL=(ALL) NOPASSWD:ALL"] + shell: /bin/bash + network: + renderers: ['netplan', 'eni', 'sysconfig'] + # Automatically discover the best ntp_client + ntp_client: auto + # Other config here will be given to the distro class and/or path classes + paths: + cloud_dir: /var/lib/cloud/ + templates_dir: /etc/cloud/templates/ + upstart_dir: /etc/init/ + package_mirrors: + - arches: [i386, amd64] + failsafe: + primary: http://archive.ubuntu.com/ubuntu + security: http://security.ubuntu.com/ubuntu + search: + primary: + - http://%(ec2_region)s.ec2.archive.ubuntu.com/ubuntu/ + - http://%(availability_zone)s.clouds.archive.ubuntu.com/ubuntu/ + - http://%(region)s.clouds.archive.ubuntu.com/ubuntu/ + security: [] + - arches: [arm64, armel, armhf] + failsafe: + primary: http://ports.ubuntu.com/ubuntu-ports + security: http://ports.ubuntu.com/ubuntu-ports + search: + primary: + - http://%(ec2_region)s.ec2.ports.ubuntu.com/ubuntu-ports/ + - http://%(availability_zone)s.clouds.ports.ubuntu.com/ubuntu-ports/ + - http://%(region)s.clouds.ports.ubuntu.com/ubuntu-ports/ + security: [] + - arches: [default] + failsafe: + primary: http://ports.ubuntu.com/ubuntu-ports + security: http://ports.ubuntu.com/ubuntu-ports + ssh_svcname: ssh diff --git a/sysadmin-ii-sys265/configs/docker-01/hosts b/sysadmin-ii-sys265/configs/docker-01/hosts new file mode 100644 index 0000000..ea6da9b --- /dev/null +++ b/sysadmin-ii-sys265/configs/docker-01/hosts @@ -0,0 +1,9 @@ +127.0.0.1 localhost +127.0.1.1 docker01-charlotte + +# The following lines are desirable for IPv6 capable hosts +::1 ip6-localhost ip6-loopback +fe00::0 ip6-localnet +ff00::0 ip6-mcastprefix +ff02::1 ip6-allnodes +ff02::2 ip6-allrouters diff --git a/sysadmin-ii-sys265/configs/mgmt-01/README.md b/sysadmin-ii-sys265/configs/mgmt-01/README.md new file mode 100644 index 0000000..76036d9 --- /dev/null +++ b/sysadmin-ii-sys265/configs/mgmt-01/README.md @@ -0,0 +1 @@ +mgmt01-charlotte diff --git a/sysadmin-ii-sys265/docker_proj1/Dockerfile b/sysadmin-ii-sys265/docker_proj1/Dockerfile new file mode 100644 index 0000000..f804562 --- /dev/null +++ b/sysadmin-ii-sys265/docker_proj1/Dockerfile @@ -0,0 +1,15 @@ +# use this version of python +FROM python:3.12-slim + +# create a working directory and copy requirements file to it +WORKDIR /app +COPY app/requirements.txt /app/requirements.txt + +# install dependencies +RUN pip install --no-cache-dir -r requirements.txt + +# copy the rest of the files to working directory +COPY app /app + +# run the python script when the container starts +CMD ["python", "app.py"] diff --git a/sysadmin-ii-sys265/docker_proj1/README.md b/sysadmin-ii-sys265/docker_proj1/README.md new file mode 100644 index 0000000..012dc73 --- /dev/null +++ b/sysadmin-ii-sys265/docker_proj1/README.md @@ -0,0 +1,143 @@ +# SYS265 - Mini Docker Project +flask web-chat app with docker +___ + + +>[!Note] +> I've been learning some network programming lately, so most of the python is my own. but I did use AI for the Dockerfile, some of the javascript, and general troubleshooting (netwoking in a Docker container can get confusing) + +## Project Structure +``` +├── docker-chat +│   ├── app +│   │   ├── app.py +│   │   ├── requirements.txt +│   │   └── templates +│   │   └── index.html +│   ├── docker-compose.yml +│   └── Dockerfile +``` + +___ +## 1. create [app.py](https://git.charlotte.sh/lotte/ChamplainTechJournals/src/branch/main/sysadmin-ii-sys265/docker_proj1/app/app.py) +this is the python/flask backend for the web app. it will open a websocket on port 5000 and handle message sent over it. +``` +from flask import Flask, render_template +from flask_socketio import SocketIO, send + +# initialize flask and socketio +app = Flask(__name__) +socketio = SocketIO(app) + +# default page +@app.route('/') +def index(): + return render_template('index.html') + +# runs when message is received on socket +@socketio.on('message') +def handle_message(msg): + print("message: " + msg) + send(msg, broadcast=True) + +# open websocket, listen on port 5000 +if __name__ == '__main__': + socketio.run(app, host='0.0.0.0', port=5000, allow_unsafe_werkzeug=True) +``` + +## 2. create [index.html](https://git.charlotte.sh/lotte/ChamplainTechJournals/src/branch/main/sysadmin-ii-sys265/docker_proj1/app/templates/index.html) +this is the html frontend for the web page, as well as some javascript to be a medium between network connections and the frontend webpage +``` + + + +sys265 chat + + + + +
    + + + + + + + + + + +``` + +## 3. create [requirements.txt](https://git.charlotte.sh/lotte/ChamplainTechJournals/src/branch/main/sysadmin-ii-sys265/docker_proj1/app/requirements.txt) +this includes necessary dependencies. they will be installed via Dockerfile +``` +Flask==2.2.2 +flask-socketio==5.3.2 +werkzeug==2.2.2 +``` + +## 4. create [docker-compose.yml](https://git.charlotte.sh/lotte/ChamplainTechJournals/src/branch/main/sysadmin-ii-sys265/docker_proj1/docker-compose.yml) +this defines the services to be used. while this could work without the chat-net network, creating an isolated network made setting this up simpley imo, especially since we are already running wordpress. +``` +version: '3.8' + +services: + chat-server: + build: . + ports: + - "5000:5000" + volumes: + - ./app:/app + networks: + - chat-net + +networks: + chat-net: + driver: bridge +``` + +## 5. create [Dockerfile](https://git.charlotte.sh/lotte/ChamplainTechJournals/src/branch/main/sysadmin-ii-sys265/docker_proj1/Dockerfile) +``` +# use this version of python +FROM python:3.12-slim + +# create a working directory and copy requirements file to it +WORKDIR /app +COPY app/requirements.txt /app/requirements.txt + +# install dependencies +RUN pip install --no-cache-dir -r requirements.txt + +# copy the rest of the files to working directory +COPY app /app + +# run the python script when the container starts +CMD ["python", "app.py"] +``` + +## 6. run docker-compose +``` +cd docker-chat +docker-compose up -d +``` +![image](../../assets/5e739863-3710-4ea0-8988-2a9c56ddb981.png) diff --git a/sysadmin-ii-sys265/docker_proj1/app/app.py b/sysadmin-ii-sys265/docker_proj1/app/app.py new file mode 100644 index 0000000..c92138a --- /dev/null +++ b/sysadmin-ii-sys265/docker_proj1/app/app.py @@ -0,0 +1,21 @@ +from flask import Flask, render_template +from flask_socketio import SocketIO, send + +# initialize flask and socketio +app = Flask(__name__) +socketio = SocketIO(app) + +# default page +@app.route('/') +def index(): + return render_template('index.html') + +# runs when message is received on socket +@socketio.on('message') +def handle_message(msg): + print("message: " + msg) + send(msg, broadcast=True) + +# open websocket, listen on port 5000 +if __name__ == '__main__': + socketio.run(app, host='0.0.0.0', port=5000, allow_unsafe_werkzeug=True) diff --git a/sysadmin-ii-sys265/docker_proj1/app/requirements.txt b/sysadmin-ii-sys265/docker_proj1/app/requirements.txt new file mode 100644 index 0000000..7b6d685 --- /dev/null +++ b/sysadmin-ii-sys265/docker_proj1/app/requirements.txt @@ -0,0 +1,3 @@ +Flask==2.2.2 +flask-socketio==5.3.2 +werkzeug==2.2.2 diff --git a/sysadmin-ii-sys265/docker_proj1/app/templates/index.html b/sysadmin-ii-sys265/docker_proj1/app/templates/index.html new file mode 100644 index 0000000..3c9de52 --- /dev/null +++ b/sysadmin-ii-sys265/docker_proj1/app/templates/index.html @@ -0,0 +1,38 @@ + + + +sys265 chat + + + + +
      + + + + + + + + + + diff --git a/sysadmin-ii-sys265/docker_proj1/docker-compose.yml b/sysadmin-ii-sys265/docker_proj1/docker-compose.yml new file mode 100644 index 0000000..32ef164 --- /dev/null +++ b/sysadmin-ii-sys265/docker_proj1/docker-compose.yml @@ -0,0 +1,15 @@ +version: '3.8' + +services: + chat-server: + build: . + ports: + - "5000:5000" + volumes: + - ./app:/app + networks: + - chat-net + +networks: + chat-net: + driver: bridge diff --git a/sysadmin-ii-sys265/labs/lab00-environment-setup.md b/sysadmin-ii-sys265/labs/lab00-environment-setup.md new file mode 100644 index 0000000..2231322 --- /dev/null +++ b/sysadmin-ii-sys265/labs/lab00-environment-setup.md @@ -0,0 +1,51 @@ +# Lab00 - Routing and Windows + +Our goal is to build a realistic server environment consisting of a routed network (LAN and WAN) as well as introduce Server 2019 Desktop and Core and the systems required to manage them. + +## FW01 and WKS01 +- [use this doc](https://git.charlotte.sh/lotte/ChamplainTechJournals/src/branch/main/sysadmin-i-sys255/lab01-environment-setup.md), configuration is exactly the same + +## AD01 +- (admin password is `password123!`) +- `sconfig` \ +![image](../assets/b42fc4c4-07fe-44e1-ae48-59a1ea275408.png) + +- Invoke powershell and install Active Directory: `Install-WindowsFeature AD-Domain-Services -IncludeManagementTools` \ +![image](../assets/2a087f38-8b59-4497-9162-1631205d0150.png) + +- Install the Forest: `Install-ADDSForest -DomainName charlotte.local` \ +![image](../assets/b295e94c-3da4-4dbe-98d5-45f25a4da00a.png) + +- You should be in a domain now \ +![image](../assets/73076712-88fa-4c39-866b-da138c52002d.png) + +### creating domain users (one user, one admin): +- `net user charlotte.croce password123! /ADD /DOMAIN` +- `net user charlotte.croce-adm password123! /ADD /DOMAIN` +- `net group "Domain Admins" charlotte.croce-adm /ADD /DOMAIN` + + +## MGMT01 +MGMT01 is a Server 2019 with GUI. Its job will be to remotely manage any server core systems. +password: `password123!` \ +![image](../assets/b752ce4c-f831-4619-b563-9a2ff9eb57c5.png) + +to join domain: +- `sconfig` -> 1 -> D -> charlotte.local -> Administrator -> type Administrator password in prompt -> restart +- login as the charlotte.croce-adm domain user + +adding ad01 to management scope +- server manager - add roles and features +- add the following features: \ +![image](../assets/25634b91-4a27-4ff5-a218-337fab157561.png) +![image](../assets/f1b9d632-2664-4209-beae-3ee167b93a76.png) + +- create DNS records: [use this doc](https://git.charlotte.sh/lotte/ChamplainTechJournals/src/branch/main/sysadmin-i-sys255/lab02-dns%2Badds-role.md) +- note: it's easier to create the reverse lookup zone first, as PTR records will be created automatically when you create a new A record, although you will still have to manually create some PTRs +![image](../assets/1fc7982f-2d40-49d2-8264-356db5fb0d8c.png) +![image](../assets/d750c565-6a8c-4867-8da3-949046bb5a1e.png) + +- finally, join wks01 to the domain +- before doing so, we must change the DNS server to 10.0.5.5, to recognize charlotte.local +![image](../assets/f7c0d739-296c-4fab-96b2-4afe4439aee6.png) + diff --git a/sysadmin-ii-sys265/labs/lab01-network-management.md b/sysadmin-ii-sys265/labs/lab01-network-management.md new file mode 100644 index 0000000..f3349e7 --- /dev/null +++ b/sysadmin-ii-sys265/labs/lab01-network-management.md @@ -0,0 +1,63 @@ +# lab01- Network Management + +## nmon1-charlotte +- setup with hostname, username, networking (10.0.5.11, remember: add `charlotte.local` to search domain) +- add record to DNS manager \ +![image](../assets/40d632c5-18c8-42b0-a938-19f6aabce1d0.png) + +``` +I had trouble reaching the internet on nmon1, then realized fw01 couldn't reach the internet as well. +idk what happened but I rebooted fw01 and it worked again +``` + +## enable SNMP services on pfSense +- web dashboard (10.0.5.2) +- services -> SNMP \ +![image](../assets/27e9470d-e84b-4e8b-8076-cfcbc9b54dea.png) \ +![image](../assets/bcdeb3dd-1245-4fc0-aff3-0a84cb383c8f.png) +- restart SNMP service \ +![image](../assets/727824d9-510f-4235-8e62-7360a41ebae2.png) + + +## Install and Test SNMP Client on nmon01 +- `sudo yum install net-snmp-utils` \ +![image](../assets/c2924ebd-c975-4cbf-9b0e-b26e36954fdb.png) + +## Install SNMPD (a SNMP Server) on web01 +- set up web01 (10.0.5.12, you know the drill by now) +- `sudo yum install net-snmp-utils net-snmp` +- The default snmp configuration does not suit our purpose. Make a backup copy of /etc/snmp/snmpd.conf and create a new/blank version. + - `sudo cp /etc/snmp/snmpd.conf /etc/snmp/snmpd.conf.backup` \ +![image](../assets/38e9d23f-a37a-4e61-948c-b949cbb19acc.png) +- allow 161/udp through firewall +``` +sudo firewall-cmd --add-port=161/udp --permanent` +sudo firewall-cmd --reload` +``` +- enable/start snmpd +``` +sudo systemctl enable snmpd +sudo systemctl start snmpd +``` + +## install the SNMP Service Feature on AD01 using Server Manager on MGMT +## install the SNMP-Tools Remote Administration Feature on MGM01 +![image](../assets/545f45bb-c125-4f69-9447-b605773f26be.png) \ +![image](../assets/f62408cf-24bd-4947-9277-df5637f800e5.png) + + +## Enable Remote Management on AD01 +Remote Computer Management does not work immediately for our remote AD01 Server due to firewall restrictions as seen in the error message. \ +![image](../assets/f6c94f07-746a-4cc1-8f09-db5eb76f08a5.png) \ +You will need to fix this by invoking a remote PowerShell session with AD01 from mgmt01. \ +![image](../assets/b60a950e-bc09-424d-93cc-38c55deb0105.png) + +## SNMP Service Security Properties on AD01 +- Adjust the SNMP service properties on AD01 to add the SYS265 community string and limit queries to those from nmon01. \ +![image](../assets/2629d201-965b-4a1e-8afe-7b88ebcbddd9.png) +- Restart the SNMP Service on ad01 + + +## Capturing snmp packets nmon01->web01 +- on web01: `tcpdump -i ens192 port 161 -c10 -AAA` +- on nom01: `snmpwalk -Os -c SYS265 -v2c web01-charlotte system` diff --git a/sysadmin-ii-sys265/labs/lab02-dhcp.md b/sysadmin-ii-sys265/labs/lab02-dhcp.md new file mode 100644 index 0000000..e446051 --- /dev/null +++ b/sysadmin-ii-sys265/labs/lab02-dhcp.md @@ -0,0 +1,15 @@ +# DHCP Lab +[reference from SYS255](https://git.charlotte.sh/lotte/ChamplainTechJournals/src/branch/main/sysadmin-i-sys255/lab08.5-configure-windows-dhcp-server.md) + +ad01- add roles and features \ +![image](../assets/57c507d3-202d-4f0b-a19e-3da3bf8f3450.png) + +DNS Manager +Configurations: +- Scope: 10.0.5.150 - 10.0.5.175 +- Subnet mask: /24 +- Router: 10.0.5.2 +- DNS: 10.0.5.5 + +on wks-01, set IP to acquire automatically \ +![image](../assets/0dbd53ce-1e87-4aa7-8c4d-e592233d9f19.png) diff --git a/sysadmin-ii-sys265/labs/lab03-docker.md b/sysadmin-ii-sys265/labs/lab03-docker.md new file mode 100644 index 0000000..85306dd --- /dev/null +++ b/sysadmin-ii-sys265/labs/lab03-docker.md @@ -0,0 +1,181 @@ +# Containerization with Docker +![image](https://git.charlotte.sh/lotte/ChamplaintechJournals/src/branch/main/assets/7a571e73-76f3-4efe-a4dd-644c0c856011.png) + +## set up docker01 - Ubuntu 20.04 cloud server +IP Address: 10.0.5.12 (change web01 address to 10.0.5.20) \ +Default Gateway: 10.0.5.2 \ +DNS: 10.0.5.5 \ +![image](https://git.charlotte.sh/lotte/ChamplaintechJournals/src/branch/main/assets/e8491101-e466-4046-be31-eb397ee2f159.png) + +### changing hostname. it is different on Ubuntu Cloud +- in `/etc/cloud/cloud.cfg`: +``` +preserve_hostname: true +hostname: docker01-charlotte (add this line under) +fqdn: docker01-charlotte.charlotte.local (add this line under) +``` +- change hostname for 127.0.1.1 in `/etc/hosts` file + +![image](https://git.charlotte.sh/lotte/ChamplaintechJournals/src/branch/main/assets/c921d829-5bc4-4048-a4fb-de42b1f413a7.png) + +- finally, `sudo hostnamectl hostname docker01-charlotte` +- update DNS records on mgmt01 (remember to change web01 record too) + +## docker installation +https://www.digitalocean.com/community/tutorials/how-to-install-and-use-docker-on-ubuntu-20-04 + +update and install prerequisite packages, this will let apt use packages over HTTPS +``` +sudo apt update +sudo apt install apt-transport-https ca-certificates curl software-properties-common +``` +add the GPG key +``` +curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - +``` +add docker repo to APT sources +``` +sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu focal stable" +``` +validate installation is from docker repo. Notice that docker-ce is not installed, +but the candidate for installation is from the Docker repository for Ubuntu 20.04 (focal). +``` +apt-cache policy docker-ce | head +``` +![image](https://git.charlotte.sh/lotte/ChamplaintechJournals/src/branch/main/assets/bb0207b1-5010-4d36-9fdd-028ec450cc5e.png) + +install docker +``` +sudo apt install docker-ce +``` + +check status +``` +sudo systemctl status docker +``` + +### executing the docker command without sudo: +add user to the docker group, apply the new group membership, and logout/log back in +``` +sudo usermod -aG docker charlotte +su - charlotte +``` + +## using docker +### downloading images +search for images availabe on Docker Hub +``` +docker search +``` +download from Dockuer Hub +``` +docker pull +``` +see installed images +``` +docker images +``` + + +## docker-compose +- https://www.digitalocean.com/community/tutorials/how-to-install-and-use-docker-compose-on-ubuntu-20-04 +> "Docker Compose is a tool that allows you to run multi-container application environments based on definitions set in a YAML file." + +download the 1.29.2 release and save the executable file at /usr/local/bin/docker-compose +``` +sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose +``` +make docker-compose executable: +``` +sudo chmod +x /usr/local/bin/docker-compose +``` +verify installation +``` +docker-compose --version +``` + +The following command pulls down an Arch Linux based docker image, invokes it in a container, and runs /bin/echo "HELLO SYS265 SNOWY DAYS '' before deleting the container. +``` +docker run --rm archlinux:latest /bin/echo "HELLO SYS265 SNOWY DAYS" +``` + + +___ + +## docker run command syntax (example) +- e.g. The following command will pull down the image, application and dependencies associated with a simple python web application. `docker run -d -P training/webapp python app.py` +- `docker`: CLI for interacting with docker +- `run`: create and start a new container +- `-d` (or `--detach`): the container runs in the background. + - useful for non-interactive services, like webservers and databases +- `-P` (or `--publich-all`): automatically publishes all exposed ports of the container to random host ports. + - This allows external access to the services running in the container without having to specify port mappings manually. +- `training/webapp`: the docker image from which the container is created + - In this case, an image named `webapp` that is located in the `training` repository +- `python`: command that will be executed inside the container once it starts +- `app.py`: argument passed to the python command + - the Python script `app.py` should be executed by the Python interpreter when the container starts. + + +- `docker run httpd` will automatically set up an apache web server in the container + +### to stop docker process +``` +docker stop +``` + +## dockerized WordPress +https://github.com/docker/awesome-compose/tree/master/wordpress-mysql + +- create a directory `docker-wp` +- create compose.yml +>[!Caution] +> Absolutely never use a tab in a docker-compose.yml file + +``` +services: + db: + # We use a mariadb image which supports both amd64 & arm64 architecture + image: mariadb:10.6.4-focal + # If you really want to use MySQL, uncomment the following line + #image: mysql:8.0.27 + command: '--default-authentication-plugin=mysql_native_password' + volumes: + - db_data:/var/lib/mysql + restart: always + environment: + - MYSQL_ROOT_PASSWORD=somewordpress + - MYSQL_DATABASE=wordpress + - MYSQL_USER=wordpress + - MYSQL_PASSWORD=wordpress + expose: + - 3306 + - 33060 + wordpress: + image: wordpress:latest + ports: + - 80:80 + restart: always + environment: + - WORDPRESS_DB_HOST=db + - WORDPRESS_DB_USER=wordpress + - WORDPRESS_DB_PASSWORD=wordpress + - WORDPRESS_DB_NAME=wordpress +volumes: + db_data: +``` + +- `docker compose up -d` +- wait...it's really that easy? + - yes + +___ + +### showing how containers use the same kernel as the host +- example: the following commands will: + - Print out the current version of Ubuntu on docker01. `cat /etc/lsb-release` + - Print out the current version of docker01's linux kernel. `echo "Current Kernel is: $(uname -a)"` + - Invoke a container of the stored Ubuntu image as well as an interactive bash command prompt, and print out the kernel being used by the Ubuntu container. `docker run -it archlinux /bin/uname -a` +![image](../assets/4df08b6e-cbf7-474b-8301-f2f52e65ba4d.png) +- as you can see, both the docker container(archlinux) and the host(docker01-charlotte) are using the same kernels + diff --git a/sysadmin-ii-sys265/labs/lab04-git-and-linux-ssh.md b/sysadmin-ii-sys265/labs/lab04-git-and-linux-ssh.md new file mode 100644 index 0000000..fdcbe73 --- /dev/null +++ b/sysadmin-ii-sys265/labs/lab04-git-and-linux-ssh.md @@ -0,0 +1,59 @@ +# Git and Linux SSH + +>[!Note] +>This entry is pretty empty because I've already written [this journal Entry for using git/github](https://git.charlotte.sh/lotte/ChamplainTechJournals/src/branch/main/automation-sys320/week01/github_setup.md) + +# Automating ssh authentication +- generate SSH key pair on your management node (in this case, web-01) +- push pubkey to github repo +- run the secure-ssh.sh script on remote host to create a new user that has the pubkey in `.../.ssh/authorized_keys` +- you can now ssh from web-01 to remote hosts without password! + +___ +### creating/adding ssh key +``` +ssh-keygen -t rsa -b 4096 -C "sys265" +cat ~/.ssh/id_rsa +``` +copy this to github SSH & GPG section +- to test: `ssh -T git@github.com` +- `git remote -v` + - if git is using https. you will have to change it to use ssh + - `git remote set-url origin git@github.com:charlottecroce/champlaintechjournals` +___ +before being able to commit, you will have to add the following authentication: +- `git config user.email charlotte.croce@mymail.champlain.edu` +- `git config user.name charlottecroce` + +## docker-01 +copying config files to git repo +``` +sudo apt install git +git clone https://git.charlotte.sh/lotte/ChamplainTechJournals +cd ~/champlaintechjournals/sysadmin-ii-sys265/configs/docker-01 +sudo cp /etc/hosts . +sudo cp /etc/netplan/* . +sudo cp /etc/cloud/cloud.cfg . +``` + +## mgmt-01 +- install git from web +``` +git clone https://git.charlotte.sh/lotte/ChamplainTechJournals +cd ~/champlaintechjournals/sysadmin-ii-sys265/configs/mgmt-01 +echo $(hostname) > README.md +git add . +git commit -m "added a readme" +git push +``` +- login with token authentication + +# web-01 +- `sudo yum install git` +- create ssh key and connect to git with it (see above section) +``` +mkdir -p linux/public-keys +mkdir -p linux/ubuntu +mkdir -p linux/centos7 +``` +- create [secure-ssh.sh script](https://git.charlotte.sh/lotte/ChamplainTechJournals/src/branch/main/sysadmin-ii-sys265/linux/centos7/secure-ssh.sh) diff --git a/sysadmin-ii-sys265/labs/lab05-ansible-automation.md b/sysadmin-ii-sys265/labs/lab05-ansible-automation.md new file mode 100644 index 0000000..7d9bf46 --- /dev/null +++ b/sysadmin-ii-sys265/labs/lab05-ansible-automation.md @@ -0,0 +1,322 @@ +# Automation with Ansible +Demonisioning: web01, nmon-01, docker-01 😢 +___ +## New Machines +### controller-charlotte - Ubuntu +configure with netplan +``` +network: + ethernets: + ens160: + dhcp4: no + addresses: + - 10.0.5.90/24 + routes: + - to: default + via: 10.0.5.2 + nameservers: + addresses: + - 10.0.5.5 + version: 2 +``` +#### to reset DNS +``` +dhclient -r +dhclient +``` +### ansible1-charlotte - CentOS +configure with nmtui +- IP: 10.0.5.91 +- DG: 10.0.5.2 +- DNS: 10.0.5.5 +### ansible2-charlotte - CentOS +configure with nmtui +- IP: 10.0.5.92 +- DG: 10.0.5.2 +- DNS: 10.0.5.5 + +## Initial Configuration +- on all machines, create a sudo account named deployer (use same password across all systems) +- install ansible on controller +``` +sudo apt install ansible sshpass python3-paramiko +``` +- Configure sudo access: + - create `/etc/sudoers.d/sys265` on all systems + - add the following line to allow passwordless sudo for deployer: + ``` + deployer ALL=(ALL) NOPASSWD:ALL + ``` + +> [!Note] +> Although it is not uncommon to update `/etc/sudoers` directly, it is far easier to script the addition of a file to `/etc/sudoers.d` + + +## SSH Key Setup +As the deployer user on controller: +- Create RSA keypair with passphrase: +``` +ssh-keygen -t rsa +``` +- copy pukey to ansible1 and ansible2 +``` +ssh-copy-id deployer@ansible1-charlotte +ssh-copy-id deployer@ansible2-charlotte +``` +-configure `ssh-agent` to avoid typing passphrase for 4 hours +``` +eval(ssh-agent) # test to see if ssh-agent is running, and if not,run it +ssh-add -t 14400 +``` +## Ansible Configuration +in `deployer@controller:/home/deployer/` +- make directory structure +``` +mkdir -p ansible/roles +cd ansible/ +``` +- create inventory and test conection +``` +echo ansible1-charlotte >> inventory.txt +echo ansible2-charlotte >> inventory.txt +cat inventory.txt +``` +``` +ansible all -m ping -i inventory.txt +``` + +- add webmin tag to `inventory.txt` and test + +``` +ansible1-charlotte +[webmin] +ansible2-charlotte +``` + +``` +deployer@controller-charlotte:~/ansible$ ansible webmin -m ping -i inventory.txt +ansible2-charlotte | SUCCESS => { + "ansible_facts": { + "discovered_interpreter_python": "/usr/libexec/platform-python" + }, + "changed": false, + "ping": "pong" +} +``` + +## webmin installation +- install webmin role +``` +ansible-galaxy install semuadmin.webmin -p roles/ +``` +- create `webmin.yml` playbook to handle repository setup, installation, and firewall configuration +``` +- name: webmin sys265 + hosts: webmin + become: true # Run all tasks with sudo/root privileges + vars: + install_utilities: false + firewalld_enable: true + + pre_tasks: # before role execution. we need the repo/key before executing webmin installation role + - name: add webmin repo and GPG key + yum_repository: + name: webmin + description: Webmin Distribution Neutral + baseurl: http://download.webmin.com/download/yum + enabled: true + gpgcheck: true + gpgkey: http://www.webmin.com/jcameron-key.asc + + # update YUM cache to recognize new repository + - name: clean and update YUM cache + yum: + update_cache: yes + + roles: + - semuadmin.webmin # apply the webmin installation role + + handlers: # will run when a task has notify:name parameter + - name: reload firewall # runs after adding firewall rule + command: firewall-cmd --reload + + tasks: + # open port 10000 in firewall for webmin web interface + - name: add firewall rule + firewalld: + port: 10000/tcp + permanent: true + state: enabled + notify: reload firewall + + - name: install webmin + yum: + name: webmin + state: present # will only install if not already + + - name: enable and start webmin service + systemd: + name: webmin + enabled: true + state: started + daemon_reload: yes # reload systemd to recognize new service +``` +- run playbook +``` +ansible-playbook -i inventory.txt roles/webmin.yml +``` +- change webmin root password +``` + sudo /usr/libexec/webmin/changepass.pl /etc/webmin root newpassword +``` + + +## apache isntallation +- edit inventory.txt +``` +[apache] +ansible1-charlotte +[webmin] +ansible2-charlotte +``` +- install apache role +``` +ansible-galaxy install geerlingguy.apache -p roles/ +``` +- create `apache.yml` file +``` +- name: apache sys265 + hosts: apache + become: true # Run all tasks with sudo/root privileges + vars: + install_utilities: false + firewalld_enable: true + ansible_os_family: RedHat + ansible_distribution: CentOS # required because role searches for Rocky config files + roles: + - geerlingguy.apache # apply the apache installation role + + handlers: # will run when a task has notify:name parameter + - name: reload firewall # runs after adding firewall rule + command: firewall-cmd --reload + + tasks: + # open port 443 in firewall for apache web interface + - name: add firewall rule + firewalld: + port: "{{ item }}" + permanent: true + immediate: true + state: enabled + loop: + - 80/tcp + - 443/tcp + notify: reload firewall + + - name: install apache + yum: + name: httpd + state: present # will only install if not already + + - name: enable and start apache service + systemd: + name: httpd + enabled: true + state: started + daemon_reload: yes # reload systemd to recognize new service + +``` +- run playbook +``` +ansible-playbook -i inventory.txt roles/webmin.yml +``` + +# Ansible on Windows +## OpenSSH Server Setup + +>[!Caution] +> DO NOT INSTALL 32 BIT VERSION + +### Install OpenSSH +Run these commands in PowerShell as Administrator: +``` +wget https://github.com/PowerShell/Win32-OpenSSH/releases/download/v9.8.1.0p1-Preview/OpenSSH-Win64.zip -O 'C:\Program Files\OpenSSH.zip' +Expand-Archive -Path 'C:\Program Files\OpenSSH.zip' -DestinationPath 'C:\Program Files\OpenSSH' +rm 'C:\Program Files\OpenSSH.zip' +powershell.exe -ExecutionPolicy Bypass -File 'C:\Program Files\OpenSSH\OpenSSH-Win64\install-sshd.ps1' +``` +### Configure OpenSSH +- start service +``` +Start-Service sshd +Set-Service -Name sshd -StartupType 'Automatic' +Get-Service -Name sshd # check if running +``` +- add firewall rule +``` +New-NetFirewallRule -Name sshd -DisplayName 'OpenSSH Server' -Enabled True -Direction Inbound -Protocol TCP -Action Allow -LocalPort 22 +Get-NetFirewallRule | Where-Object DisplayName -Like '*ssh*' +``` +- set PowerShell as default SSH shell +``` +Set-ItemProperty "HKLM:\Software\Microsoft\Powershell\1\ShellIds" -Name ConsolePrompting -Value $true +New-ItemProperty -Path HKLM:\SOFTWARE\OpenSSH -Name DefaultShell -Value "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -PropertyType String -Force +``` +- add `charlotte.croce-adm` to the **Remote Management Users** groups +- Add/uncomment the following lines in C:\ProgramData\ssh\sshd_config + - `StrictModes no` is sometimes needed on Windows systems because Windows permissions don't map perfectly to the UNIX-style permissions that OpenSSH expects +``` +AllowUsers charlotte\charlotte.croce-adm +StrictModes no +``` +## Ansible Setup +### Inventory Setup +- add windows machines to `inventory.txt` +``` +[windows] +mgmt01-charlotte +wks01-charlotte +[windows:vars] +ansible_shell_type=powershell +``` +- create ansible.cfg in ansible directory, to skip host key checking +``` +[defaults] +host_key_checking = false +``` +- test connection +``` +ansible windows -i inventory.txt -m win_ping -u charlotte.croce-adm@charlotte.local --ask-pass +``` + +## Software deployment using win_chocolatey +- create playbook `roles/windows_software.yml` +``` +- name: install windows applications + hosts: windows + tasks: + - name: install firefox and 7zip + win_chocolatey: + name: + - firefox + - 7zip + state: present +``` +- run playbook +``` +ansible-playbook -i inventory.txt roles/windows_software.yml -u charlotte.croce-adm@charlotte.local --ask-pass +``` +- If you encounter .NET Framework errors, install version 4.8 (in my case I needed version 4.8, it will probably be a different version in the future) +``` +Invoke-WebRequest -Uri "https://go.microsoft.com/fwlink/?linkid=2088631" -OutFile "C:\dotNetFx48.exe" +Start-Process -FilePath "C:\dotNetFx48.exe" -ArgumentList "/quiet /norestart" -Wait +Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full" -Name Release # verify installation +``` +> [!Note] +> Installation may take several minutes. System restart required after installation. + +- list packages installed with chocolatey +``` +'C:\ProgramData\chocolatey\bin\choco.exe' list +``` + diff --git a/sysadmin-ii-sys265/labs/lab06-ad-gpo-sw-deployment.md b/sysadmin-ii-sys265/labs/lab06-ad-gpo-sw-deployment.md new file mode 100644 index 0000000..bb4e515 --- /dev/null +++ b/sysadmin-ii-sys265/labs/lab06-ad-gpo-sw-deployment.md @@ -0,0 +1,69 @@ +# AD Group Policy & SW Deployment + + +## Prepare an OU, user & workstation +Before we get into configuring a Group Policy Object (GPO) within Active Directory (AD), let’s set the AD stage to deploy a software package. Via AD Users & Computers, create a “Test OU”. + +![image](../../assets/a5a9d811-0e27-48e2-b25d-97cb9e345e56.png) + +Use Powershell on AD01 via MGMT01 to create another OU called “Software Deploy”, move WKS01 and your regular named account into it, and then delete the Test OU. +```powershell +# Create another OU called Software Deploy under charlotte.local +# Move WKS01 and your regular named account into it, and then +# Delete the Test OU + +# Get the domain Distinguished Name (DN) +$domainDN = (Get-ADDomain).DistinguishedName + +# Create the "Software Deploy" OU +$swDeployOUDN = "OU=Software Deploy,$domainDN" +$swDeployOU = Get-ADOrganizationalUnit -Identity $swDeployOUDN +if($swDeployOU){ + Write-Host "'Software Deploy' OU already exists at $swDeployOUDN" +}else{ + New-ADOrganizationalUnit -Name "Software Deploy" -Path $domainDN -Description "Software Deployment OU" + Write-Host "Created $swDeployOUDN" +} + +# Move WKS01 computer to new OU +$computerDN = (Get-ADComputer -Identity "WKS01-CHARLOTTE").DistinguishedName +$targetOUDN = "OU=Software Deploy,$domainDN" +Move-ADObject -Identity $computerDN -TargetPath $targetOUDN +Write-Host "Computer $computerDN added to $targetOUDN" + +# Move charlotte.croce-adm to new OU +$userDN = (Get-ADUser -Identity "charlotte.croce-adm").DistinguishedName +Move-ADObject -Identity $userDN -TargetPath $targetOUDN +Write-Host "User $userDN added to $targetOUDN" + +# Remove the "Protect from accidental deletion" flag from Test OU and delete +$testOU = Get-ADOrganizationalUnit -Filter {Name -eq "Test OU"} +if($testOU){ + Set-ADObject -Identity $testOU -ProtectedFromAccidentalDeletion $false + Remove-ADOrganizationalUnit -Identity $testOU -Confirm:$false + Write-Host "Deleted $testOU" +} +``` + +## Deploying Software via GPO + +- On MGMT01, download the current Putty x64-bit Windows Installer Package. +- Next, create a Share on MGMT01 named ‘Software’ and place Putty’s .msi in it, so users and computers (via GPO) can access & install it shortly. + - see SYS255 file share docs [here](https://git.charlotte.sh/lotte/ChamplainTechJournals/src/branch/main/sysadmin-i-sys255/lab07-lab-server-core-and-remote-administrator-tools.md#use-rsat-to-add-to-fs01-and-create-a-sales-users-share). No need to map drive to letter +- Via Group Policy Management feature on MGMT (You need to install this), create a new GPO named ‘Deploy SW’ within the Software Deploy OU. \ +![image](../../assets/64d738b7-1b8e-45ea-9f7d-474fc6679cfb.png) +![image](../../assets/dccadcee-10f4-4fce-ac7b-0f7b9b87f0cd.png) +- Edit the new GPO by creating a new Software installation, and assign Putty’s .msi package to deploy. \ +![image](../../assets/45ad5e35-665c-4861-a8be-e9aa17d6b676.png) +- With the new GPO setting, run `gpupdate /force` on WKS01, and then allow the restart when prompted. PuTTY should now be installed + +> [!Note] +> An extremely common issue you’ll encounter in MS Window environments are the differences between Local Permissions vs. Share Permissions: +> +> Local Permissions (also called NTFS Permissions): Permissions that are applied only Locally (and not Remotely) on the OS, and affects both Local (i.e. via keyboard) and Remote (i.e. via network) account access. +> +> Share Permissions: Permissions that are applied only Remotely (and not Locally) to the OS, and affects only Remote (i.e. via network shares) account access. +> +> If both Shared & Local Permissions are set, then MOST RESTRICTIVE PERMISSION WINS. #LeastPriledgeRules -- summary [here](https://blog.netwrix.com/ntfs-vs-share-permissions) + + diff --git a/sysadmin-ii-sys265/labs/lab07-certs.md b/sysadmin-ii-sys265/labs/lab07-certs.md new file mode 100644 index 0000000..bbba738 --- /dev/null +++ b/sysadmin-ii-sys265/labs/lab07-certs.md @@ -0,0 +1,149 @@ +# Lab07 - certs + +make certain -adm account is in the Enterprise Admins +```powershell +Get-ADGroupMember "Enterprise Admins" +``` +add RSAT to MGMT01. needs to run as administrator +```powershell +Install-WindowsFeature RSAT-ADCS -IncludeManagementTools +``` +Start remote PowerShell session +```powershell +$session = New-PSSession -ComputerName ad01-charlotte +``` +Install AD Certificate Services Role +```powershell +Invoke-Command -Session $session -ScriptBlock { + Install-WindowsFeature -Name AD-Certificate -IncludeManagementTools + + # Import the ADCS module + Import-Module ADCSDeployment +} +``` +Configure Enterprise Root CA +```powershell +Invoke-Command -Session $session -ScriptBlock { + Install-AdcsCertificationAuthority ` + -CAType EnterpriseRootCA ` + -CryptoProviderName "RSA#Microsoft Software Key Storage Provider" ` + -KeyLength 4096 ` + -HashAlgorithmName SHA512 ` + -ValidityPeriod Years ` + -ValidityPeriodUnits 7 ` + -Force +} +``` +Create Certificate Share +```powershell +Invoke-Command -Session $session -ScriptBlock { + # create the shared folder for certs + New-Item -Path "C:\Shares\Certs" -ItemType Directory -Force + New-SmbShare -Name "Certs" -Path "C:\Shares\Certs" -FullAccess "Domain Admins" -ChangeAccess "Authenticated Users" + + # copt cert to shared directory + $cert = Get-ChildItem -Path "Cert:\LocalMachine\CA" | Where-Object {$_.Subject -like "*charlotte-ad01-CHARLOTTE-CA*"} + + # export cert to shared folder + Export-Certificate -Cert $cert -FilePath "C:\Shares\Certs\charlotte-AD01-CHARLOTTE-CA.cer" -Type CERT +} +``` + +Install AD CS role with Certification Authority and Web Enrollment +``` +Install-WindowsFeature -Name ADCS-Cert-Authority, ADCS-Web-Enrollment -IncludeManagementTools +``` + +Configure the Subordinate CA and generate certificate request +```powershell +Install-AdcsCertificationAuthority ` + -CAType EnterpriseSubordinateCA ` + -CACommonName "mgmt01-CHARLOTTE-SubCA" ` + -CryptoProviderName "RSA#Microsoft Software Key Storage Provider" ` + -KeyLength 4096 ` + -HashAlgorithmName SHA512 ` + -OutputCertRequestFile "C:\SubCARequest.req" +``` + +Install the Web Enrollment service +```powershell +Install-AdcsWebEnrollment +``` + +Move the certificate request to the Root CA, get it signed, and retrieve it +```powershell +# Copy request to Root CA's shared folder +Copy-Item -Path "C:\SubCARequest.req" -Destination "\\ad01-charlotte\Certs\" + +# Sign the request on the Root CA +Invoke-Command -Session $session -ScriptBlock { + # Sign the subordinate CA certificate request + certreq -submit -config "ad01-charlotte\charlotte-AD01-CHARLOTTE-CA" -attrib "CertificateTemplate:SubCA" "C:\Shares\Certs\SubCARequest.req" "C:\Shares\Certs\SubCACert.cer" +} + +# Copy the signed certificate back to the Subordinate CA +Copy-Item -Path "\\ad01-charlotte\Certs\SubCACert.cer" -Destination "C:\" +``` +```powershell +# Start the CA service +Start-Service -Name CertSvc + +# Install the issued certificate +certutil -installcert "C:\SubCACert.cer" + +# Configure CA settings +certutil -setreg CA\CRLPeriodUnits 1 +certutil -setreg CA\CRLPeriod "Weeks" +certutil -setreg CA\CRLOverlapPeriodUnits 12 +certutil -setreg CA\CRLOverlapPeriod "Hours" + +# Restart the service to apply changes +Restart-Service -Name CertSvc +``` +``` +# Verify the CA status +certutil -ping +``` + +Clean up the remote session +``` +Remove-PSSession $session +``` + +___ +*at this point I stopped using PS and just used the GUI* +___ + +### Create Certificate Template +- open the CA console: `certsrv.msc` +- Expand root cert tree > RC Certificate Templates > Manage +- Duplicate User template +- General tab: Set name "Champ Lab User" +- Subject Name: Select "Build from AD info", uncheck all email options +- Extensions: Add "Smart Card Logon" to Application Policies +- Security: set "Authenticated Users" to Read, Enroll, Autoenroll permissions + +## Issue Certificate Template +- in CA console +- Right-click Certificate Templates > New > Certificate Template to Issue > Select "Champ Lab User" + +## Configure Group Policy +- `gpmc.msc` +- Create GPO "Champ Lab Users" at domain level +- Edit GPO > User Configuration > Policies > Windows Settings > Security Settings > Public Key Policies +- Enable "Certificate Services Client - Auto-Enrollment" +- Check both renewal options > OK + +## Test Auto-Enrollment +- on WKS01: +- `gpupdate /force` +- Verify: `gpresult /r` +- `certmgr.msc` > Personal > Certificates > Verify "Champ Lab User" certificate is present + +## Windows Admin Center Installation +- Download Windows Admin Center 2019 Evaluation + - https://info.microsoft.com/ww-landing-windows-admin-center.html + - download the msi + - you will have to put in information. i just used fake info +- Express setup. Generate self-signed cert. Disable updates +- Logon via -adm account, add ad01 + wks10, install AD + DNS extensions, and uninstall Azure + Cluster extensions \ No newline at end of file diff --git a/sysadmin-ii-sys265/linux/centos7/secure-ssh.sh b/sysadmin-ii-sys265/linux/centos7/secure-ssh.sh new file mode 100755 index 0000000..7b2f52e --- /dev/null +++ b/sysadmin-ii-sys265/linux/centos7/secure-ssh.sh @@ -0,0 +1,72 @@ +#!/bin/bash +# +# secure-ssh.sh +# author: charlottecroce +# +# creates a new SSH user using $1 parameter +# adds a public key from the local repo or curled from the remote repo +# removes roots ability to SSH in +# +# +# Requirements: +# must run as root +# $1 = username of new user +# + +# check if script is run as root +if [ $EUID -ne 0 ]; then + echo "run as root" + exit 1 +fi + +# check if username was provided +if [ -z $1 ]; then + echo "Usage: $0 " + exit 1 +fi + +# vars +USERNAME=$1 +AUTHORIZED_KEYS_DIR="/home/$USERNAME/.ssh" +AUTHORIZED_KEYS_FILE="$AUTHORIZED_KEYS_DIR/authorized_keys" + +# create user +useradd -m -d /home/$USERNAME -s /bin/bash $USERNAME +echo "user: <$USERNAME> created" + +# create .ssh directory, give perms to user +mkdir -p $AUTHORIZED_KEYS_DIR +chmod 700 $AUTHORIZED_KEYS_DIR + +# try to get SSH pubkey from local repo +if [ -f "/home/charlotte/champlaintechjournals/sysadmin-ii-sys265/linux/public-keys/id_rsa.pub" ]; then + echo "key found in local repo" + cat /home/charlotte/champlaintechjournals/sysadmin-ii-sys265/linux/public-keys/id_rsa.pub >> $AUTHORIZED_KEYS_FILE +else + # if local key doesn't exist, get from github repo... + echo "no key found in local repo, cloning from github..." + git clone https://git.charlotte.sh/lotte/ChamplainTechJournals /home/$USERNAME + echo "retreived key from github repo" + cat /home/$USERNAME/champlaintechjournals/sysadmin-ii-sys265/linux/public-keys/id_rsa.pub >> $AUTHORIZED_KEYS_FILE +fi + +echo "added key to $AUTHORIZED_KEYS_FILE" + +# set perms, set new user as directory owner +chmod 600 $AUTHORIZED_KEYS_FILE +chown -R $USERNAME:$USERNAME $AUTHORIZED_KEYS_DIR + +# disable root SSH login +sed -i 's/PermitRootLogin.*/PermitRootLogin no/' /etc/ssh/sshd_config +echo "Root SSH access has been disabled" + +# disable password authentication +sed -i 's/PasswordAuthentication.*/PasswordAuthentication no/' /etc/ssh/sshd_config +echo "Password authentication has been disabled" + +# Restart SSH service +echo "restarting ssh..." +systemctl restart sshd + +echo "complete!" + diff --git a/sysadmin-ii-sys265/linux/public-keys/id_rsa.pub b/sysadmin-ii-sys265/linux/public-keys/id_rsa.pub new file mode 100644 index 0000000..30710d1 --- /dev/null +++ b/sysadmin-ii-sys265/linux/public-keys/id_rsa.pub @@ -0,0 +1 @@ +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCWgOr/kpF795P2RGym4lGHD+vXFPiTpkHIA7EjIX+/cF+XB1lZgRjjgcOMf19XjspJX4XAbrAFhX82XmIdpN0ljjspy7pPvvHjRa436LW2WYX0LB80ozZiRqTV0Ic9HOpEHKeVZCbBqoO44mMKLAlsaymuhZk1qvByxap3mjXeynd5N+tDXGltN18Nsflu3twMjfHepjbUgG4H+VzQbnItN2rIe8HWRt6MCisLCrplRWHCuOMRNMhtqhgkP5IX+XSPD4SMY2ZTCXCgRAZ1I2bwPV0YzjmXkaZur39bXh9UAr2ORhrAWR+IzgLpvjAr4hsXtYantnFu6Dp7ui/Ggs29OWYXoYaIWfD7UKdyz3/xPcg5MyYnL1KSLza5Odhj12lodrrskqwfunBIIRWjp0z6LuYxdZKj4mE7+wVWN6QQiSBkPZwfMbUf3OMSGB5krxVoOy/A6Ibg2FkgzONAHeUlW9L2inrry0jVxhuamDhGaOAjt1Rhq8asKZVRU1Er1DGtJaInN/z7gvBPIUsJbZRvJUj7EoB0RdGDcH/1U6UeSt5DXz9WRPaiEss/fv4N8snIj4hd9Jt774LR2UD8ZBQkOrFOH72noLx6GDrBeIZ//Hl8rO8ja+JyeVoNLqjKzwrLhbmPsdn2/zXB0asDq2vI0yk+YUlAldG38/lhZ/9EwQ== sys265 diff --git a/sysadmin-ii-sys265/network_configuration.md b/sysadmin-ii-sys265/network_configuration.md new file mode 100644 index 0000000..c2994ec --- /dev/null +++ b/sysadmin-ii-sys265/network_configuration.md @@ -0,0 +1,38 @@ +# SYS265 - Network Configuration + +## pfsense router/gateway/firewall +upstream gateway: 10.0.17.2 \ +my unique WAN IP: 10.0.17.104 \ +net adapter 1: WAN \ +net adapter 2: LAN + +### wks01-charlotte - Windows workstation +IP address: 10.0.5.100/24 \ +Default Gateway: 10.0.5.2\ +DNS: 10.0.5.5 + +### ad01-charlotte - Windows server core +IP Address: 10.0.5.5/24 \ +Gateway: 10.0.5.2\ +DNS: 10.0.5.2 + +### mgmt01-charlotte - Windows server +IP address: 10.0.5.10/24 \ +Gateway: 10.0.5.2\ +DNS: 10.0.5.5 + + +### nmon1-charlotte - +IP address: 10.0.5.11/24 \ +Gateway: 10.0.5.2 \ +DNS: 10.0.5.5 + +### web01-charlotte - web server +IP address: 10.0.5.20/24 +Gateway: 10.0.5.2 \ +DNS: 10.0.5.5 \ + +### docker01-charlotte - +IP address: 10.0.5.12/24 +Gateway: 10.0.5.2 \ +DNS: 10.0.5.5 \ diff --git a/sysadmin-ii-sys265/windows/dhcp_check.ps1 b/sysadmin-ii-sys265/windows/dhcp_check.ps1 new file mode 100644 index 0000000..9f9740f --- /dev/null +++ b/sysadmin-ii-sys265/windows/dhcp_check.ps1 @@ -0,0 +1,97 @@ +# SYS265 - DHCP Lab +# 1/31/25 + +# Get Username +function get_username(){ + Write-Host 'Username:'$env:USERNAME +} + +# Get IP Address +function get_ip(){ + $ip_address = (Get-NetIPAddress -AddressFamily IPv4 | Select IPv4Address | Where-Object { $_.IPv4Address -ne "127.0.0.1" } | Format-Table -HideTableHeaders | Out-String).Trim() + Write-Host 'IP Address:'$ip_address +} + +# Get DHCP Server Address +function get_dhcp(){ + $dhcp_address = (Get-CimInstance Win32_NetworkAdapterConfiguration | Select DHCPServer | Format-Table -HideTableHeaders | Out-String).Trim() + Write-Host 'DHCP Server:'$dhcp_address + $dhcp_lease = (Get-CimInstance Win32_NetworkAdapterConfiguration | Select DHCPLeaseExpires | Format-Table -HideTableHeaders | Out-String).Trim() + Write-Host 'Lease Expiration:'$dhcp_lease +} + +# Get Gateway IP +function get_gateway(){ + $gateway_address = (Get-CimInstance Win32_NetworkAdapterConfiguration | Select DefaultIPGateway | Format-Table -HideTableHeaders | Out-String).Trim() + Write-Host 'Default Gateway:'$gateway_address +} + +# Get DNS Server IP +function get_dns(){ + $dns_address = ((Get-DnsClientServerAddress -AddressFamily IPv4 | Where-Object { $_.InterfaceAlias -ne "loopback" }).ServerAddresses | Out-String).Trim() + Write-Host 'DNS Server:'$dns_address +} + + +clear + +$Prompt = "`nChoose number for operation`n" +$Prompt += "1. All`n" +$Prompt += "2. Username`n" +$Prompt += "3. IP`n" +$Prompt += "4. DHCP`n" +$Prompt += "5. Default Gateway`n" +$Prompt += "6. DNS`n" +$Prompt += "7. exit" + +$operation = $true + +while($operation){ + Write-Host $Prompt | Out-String + $choice = Read-Host + Write-Host "----------" + + if($choice -eq 1){ + get_username + get_ip + get_dhcp + get_gateway + get_dns + } + + elseif($choice -eq 2){ + get_username + } + + + elseif($choice -eq 3){ + get_ip + } + + + elseif($choice -eq 4){ + get_dhcp + } + + elseif($choice -eq 5){ + get_gateway + } + + elseif($choice -eq 6){ + get_dns + } + + elseif($choice -eq 7){ + Write-Host "Goodbye" | Out-String + exit + $operation = $false + } + + else{ + Write-Host "Invalid Input" | Out-String + } + + Write-Host "----------" + +} +