tag:blogger.com,1999:blog-55366259627750649232024-03-08T12:34:23.936+01:00Tech TalkComments on computer related stuff, how to for IT specialists, development informationsTechTuxhttp://www.blogger.com/profile/10603040524421851534noreply@blogger.comBlogger115125tag:blogger.com,1999:blog-5536625962775064923.post-21552738889280647822024-02-18T22:04:00.004+01:002024-02-18T22:04:47.028+01:00Why I did drop the new Outlook after using it 6 months<p>Microsoft is currently pushing users to "beta" test the new Outlook in the same way as the new Teams client.</p><p>The new Teams desktop client for Windows is a big step forward, means you can finally be active in different tenants. Previously you had to always switch tenant to receive notifications from other tenants.</p><p>Now the new Temas client allows you to receive notifications from all tenants which you are logged in. Hurrah, MS did finaly understand how modern working is, you are often not only in one company, but you have different teams and client connections. (Of course all major competitors like slack did have this feature from the start, many many years ago)</p><p>So now the new Outlook client suggests that you will also receive better user experience compared to the "old" one.</p><p>Before switching to the new desktop client you have to know of a few (breaking) changes</p><p>1. You old addins won't work any longer, you have to look if a web version of these addins exist and install (and perhaps purchase) these. If they don't exist, your out of luck. But on the plus side, if such a plugin exists, you will also have it available in the web frontend</p><p>2. You will finaly be abke to drop the old pst files, together with all the problems comming along with them. On the backside, the search (or better the find) capability in outlook across accounts is not existent. Also moving emails/calendar entries between accounts isn't fun with the new interface and you can't automate these any longer<br /></p><p> If you can live with these, then you can consider using the new client, but stop, there are two more things, which microsoft did not tell us initially:</p><p>1. All acount data of other smtp/imap/pop3 accounts, together with all the emails etc. are sent to the microsoft servers. And yes, it's not a bug, it's a feature, to allow "better user experience" across systems. And there is no way to opt out of this account stealing, togerther with all your emails from foreign accounts</p><p>2. You can't use the new outlook desktop client to access exchange mailboxes, which have only a exchange online 1 or 2 license. If you wish to use it, then you have to upgrade the exchange online 1 or 2 license to a Microsoft365 licence which includes the desktop apps. So instead of paying 3.60 CHF/Month per mailbox (Arround 4$) you have to pay microsoft 11.20 CHF/Month for the Business Standard plan.</p><p>The last point is especially stange, but microsoft has confirmed this behaviour as the expected way of working (Read get more revenues). When you had added exchange online mailboxes to the "old" Outlook, then the automatic migration to the new outlook takes them over with no hick up and they work wonderfully in the new Outlook. Be beware, if you remove them, there is no way to re add them back, MS does a license check and denies you this.</p><p>Currently I have two employments with fully licensed Microsoft E3 enterprise tenants, and also 3 more tenants where I have full Microsoft education licenses. And even with these 5 Office 365 licenses together, I'm not allowed to open a simple Exchange Online mailbox...<br /></p><p>If you continue down this road, then microsoft might publish new Excel and Word versions, which won't allow you to open/edit documents, if they are not stored on some kind of licences microsoft storage, just plain silly.</p><p> So I started using BlueMail as my mail client for the Exchange stuff and the good old Thuderbird for all non-microsoft mailboxes. <br /></p><p> </p><p><br /></p>ZorkNikahttp://www.blogger.com/profile/00220798333873847668noreply@blogger.com0tag:blogger.com,1999:blog-5536625962775064923.post-35543358420418750382024-01-29T09:28:00.003+01:002024-01-29T09:54:58.213+01:00Selfhosting supabase in k8s with helm and keycloak sso<p><a href="https://supabase.com/" target="_blank">Supabase</a> is a free open source Firebase alternative.</p><p>The company behing the product is offering a SaaS solution and also the source code to host it yourself.</p><p>For development purposes, the selfhosting is done via docker compose.</p><p>When running it in production, in a kubernetes cluster, you can use the helm charts for this.</p><p>There are currently two helm charts available for this.</p><p><a href="https://github.com/supabase-community/supabase-kubernetes">https://github.com/supabase-community/supabase-kubernetes</a> from the community and <a href="https://bitnami.com/stack/supabase/helm">https://bitnami.com/stack/supabase/helm</a> from bitnami.</p><p>We did try both, but only got the bitnami version running.</p><p>The problem with self hosting supabase is, that you won't get any support from the company and the community seems to be small for self hosting.</p><p>So you are basically on your own when running it in production on your infrastructure.</p><p>The problem we faced with the supabase-cummunity helm chart was, that user registration via UI was not possible, apparently a known problem.</p><p>We did then try out the bitnami helm chart and got it working, with extensive googling and trying out.</p><p>The advantage of the bitnami package is, that it works similar to other bitnami packages, so you can reuse your knowledge in that area.</p><p>The final struggle we had, is to enable sso via keycloak, so we could reuse or single point of authentifaction for this.</p><p>For the whole helm chart (as of version 0.23.11) to work correctly, you have to define these things:</p><p>1. The URL of your application, let's say it's https://ai-frontend.company.com</p><p>2. The supabase URL of the supabase api, let's say it's https://supabase-api.company.com</p><p>3. The sso URL of your keycloak server, let's say it's https://sso.company.com</p><p>What we don't have at the moment, is exposing the studio url, since this needs additional authentification protection, which we did not yet get working, but that url could then be</p><p>4. https://supabase.company.com</p><p>When using the current 0.23.11 helm chart, you will receive auth errors, see https://github.com/bitnami/charts/issues/16988</p><p>To prevent these, you can use the v2.91.0 version of the docker image</p><p><span style="font-family: courier;">auth:<br /> image:<br /> registry: docker.io<br /> #<br /> # From https://github.com/bitnami/charts/issues/16988<br /> #<br /> repository: supabase/gotrue<br /> tag: v2.91.0</span><br /></p><p>The final helm values are then something like this:</p><p>publicURL: "https://supabase-api.company.com"</p><p><span style="font-family: courier;">auth:<br /> defaultConfig: |<br /> GOTRUE_API_HOST: "0.0.0.0"<br /> GOTRUE_API_PORT: {{ .Values.auth.containerPorts.http | quote }}<br /> GOTRUE_SITE_URL: "https://ai-frontend.company.com"<br /> GOTRUE_URI_ALLOW_LIST: "*"<br /> GOTRUE_DISABLE_SIGNUP: "false"<br /> GOTRUE_DB_DRIVER: "postgres"<br /> GOTRUE_JWT_DEFAULT_GROUP_NAME: "authenticated"<br /> GOTRUE_JWT_ADMIN_ROLES: "service_role"<br /> GOTRUE_JWT_AUD: "authenticated"<br /> GOTRUE_JWT_EXP: "3600"<br /> GOTRUE_EXTERNAL_EMAIL_ENABLED: "true"<br /> GOTRUE_MAILER_AUTOCONFIRM: "true"<br /> GOTRUE_SMTP_ADMIN_EMAIL: "no-reply@company.com"<br /> GOTRUE_SMTP_HOST: "inbucket.default.svc.cluster.local"<br /> GOTRUE_SMTP_PORT: "2500"<br /> GOTRUE_SMTP_SENDER_NAME: "noreply@company.com"<br /> GOTRUE_EXTERNAL_PHONE_ENABLED: "false"<br /> GOTRUE_SMS_AUTOCONFIRM: "false"<br /> GOTRUE_MAILER_URLPATHS_INVITE: "https://supabase-api.company.com/auth/v1/verify"<br /> GOTRUE_MAILER_URLPATHS_CONFIRMATION: "https://supabase-api.company.com/auth/v1/verify"<br /> GOTRUE_MAILER_URLPATHS_RECOVERY: "https://supabase-api.company.com/auth/v1/verify"<br /> GOTRUE_MAILER_URLPATHS_EMAIL_CHANGE: "https://supabase-api.company.com/auth/v1/verify"<br /> GOTRUE_EXTERNAL_KEYCLOAK_ENABLED: "true"<br /> GOTRUE_EXTERNAL_KEYCLOAK_CLIENT_ID: "Supabase_Client_ID"<br /> GOTRUE_EXTERNAL_KEYCLOAK_SECRET: "supabase-sso-client-secret"<br /> GOTRUE_EXTERNAL_KEYCLOAK_REDIRECT_URI: "https://supabase-api.company.com/auth/v1/callback"<br /> GOTRUE_EXTERNAL_KEYCLOAK_URL: "https://sso.company.com/auth/realms/MYREALM" </span><br /></p><p>These are the paramters required to get it up and running, and login via email should work now.</p><p>Unfortunally sso login will not yet work, does to some errro 502 gateway errors and no vmRoute found errors.</p><p>So the normal app url works, it the redirects you to the auth endpoint of supabase, which the redirects to your keycloak server. Once this one has sucessfully authenticated, it returns you to the supabase-api to authenticated the backend and then it should redirect you back to the original frontend.<br /></p><p>This did require some additional hours of investigation, resulting in the case, that the http headers used after keycloak authentication are to big for the default kong and our nginx ingress controller.<br /></p><p>The nasty part of finding this was, that KONG does log the access and errors in a logfile inside the pod, and does not expose then to stdout/stderr.</p><p><a href="https://github.com/bitnami/charts/issues/22755">https://github.com/bitnami/charts/issues/22755</a></p><p>The solution for the header size problem was, to tell kong about the larger headers via kong config.</p><p>kong:<br /> kong:<br /> extraEnvVars:<br /> - name: KONG_NGINX_PROXY_LARGE_CLIENT_HEADER_BUFFERS<br /> value: "64 128K"<br /> - name: KONG_NGINX_PROXY_PROXY_BUFFER_SIZE<br /> value: "128k"<br /> - name: KONG_NGINX_PROXY_PROXY_BUFFERS<br /> value: "64 128k"<br /></p><p>This did solve the kong 502 gateway error, but still our main ingress controller did struggle with the large header and returning also a 502 gateway error.<em><strong> In your nginx ingress you will see these errors:<span style="color: red;"> upstream sent too big header while reading response header from upstream.</span></strong></em></p><p>So we had to also increase these values on teh main ngin ingress controller <br /></p><p>kong:<br /> ingress:<br /> enabled: true<br /> hostname: "supabase-api.company.com"<br /> tls: true<br /> annotations:<br /> kubernetes.io/ingress.class: nginx<br /> cert-manager.io/cluster-issuer: letsencrypt-issuer<br /> acme.cert-manager.io/http01-edit-in-place: "true"<br /> nginx.org/proxy-connect-timeout: "600s"<br /> nginx.org/proxy-send-timeout: "600s"<br /> nginx.org/proxy-read-timeout: "600s"<br /> nginx.org/client-max-body-size: "20m"<br /> nginx.org/proxy-buffer-size: "256k"<br /> nginx.org/proxy-buffers: "64 512k"<br /> nginx.org/large-client-header-buffers: "64 128k"<br /> nginx.org/proxy-busy-buffers-size: "512k"<br /> # Required for keycloak sso, since the header get big<br /> # https://www.cyberciti.biz/faq/nginx-upstream-sent-too-big-header-while-reading-response-header-from-upstream/</p><p>This then finally allowed to use the keycloak sso capabality of supabase.</p><p>Don't hesitate to comment/ask here, if you need more information about the k8s setup via helm.<br /></p>ZorkNikahttp://www.blogger.com/profile/00220798333873847668noreply@blogger.com0tag:blogger.com,1999:blog-5536625962775064923.post-55971909760306855332023-02-02T18:11:00.002+01:002023-02-02T18:11:32.030+01:00Huge WindowsApps folder in 2023<p> In <a href="http://techtuxwords.blogspot.com/2022/05/cleanup-huge-windowsapps-folder.html" target="_blank">may 2022</a> we did already talk about huge WindowsApps folder under Windows 10.</p><p>All things are still valid in 2023, and also for Windows 11, with the exception that there is an enhanced cleanup script available from the <a href="https://www.tenforums.com/performance-maintenance/185009-how-clean-up-windowsapps-folder-4.html" target="_blank">TenForum </a>which also handles folder ownership stuff and can delete all orphaned folders.</p><p> </p><p>As a reference, I have a copy of the script here, in case the other forum would close/disappear some time in the future. <br /></p><p> </p><pre class="prettyprint bbcode_code prettyprinted" style="height: 372px; min-height: 10px; overflow-wrap: normal; overflow: auto; resize: both; width: 98%;"><span class="pun">::::::::::::::::::::::::::::::</span><span class="pln">
</span><span class="pun">::</span><span class="pln"> </span><span class="typ">By</span><span class="pln"> </span><span class="typ">Einstein1969</span><span class="pln"> </span><span class="kwd">for</span><span class="pln"> www</span><span class="pun">.</span><span class="pln">tenforum</span><span class="pun">.</span><span class="pln">com
</span><span class="pun">::</span><span class="pln">
</span><span class="pun">%=</span><span class="pln"> </span><span class="typ">CleanWA</span><span class="pln"> </span><span class="pun">=%</span><span class="pln"> </span><span class="lit">@set</span><span class="pln"> </span><span class="str">"Version=0.1.4.2 BETA"</span><span class="pln">
</span><span class="pun">::</span><span class="pln">
</span><span class="pun">::</span><span class="pln"> </span><span class="typ">Detect</span><span class="pln"> orphaned dirs </span><span class="kwd">in</span><span class="pln"> </span><span class="pun">%</span><span class="typ">ProgramFiles</span><span class="pun">%</span><span class="pln">\WindowsApps</span><span class="pun">,</span><span class="pln"> check </span><span class="kwd">for</span><span class="pln"> integrity</span><span class="pun">/</span><span class="pln">consistency
</span><span class="pun">::</span><span class="pln">
</span><span class="pun">::</span><span class="pln"> </span><span class="typ">Requirements</span><span class="pun">:</span><span class="pln"> </span><span class="typ">Save</span><span class="pln"> to UTF</span><span class="pun">-</span><span class="lit">8.</span><span class="pln"> </span><span class="typ">Use</span><span class="pln"> </span><span class="typ">Lucida</span><span class="pln"> </span><span class="typ">Console</span><span class="pln"> </span><span class="typ">Font</span><span class="pln"> </span><span class="kwd">in</span><span class="pln"> CMD window</span><span class="pun">.</span><span class="pln"> </span><span class="typ">Run</span><span class="pln"> </span><span class="kwd">with</span><span class="pln"> </span><span class="kwd">double</span><span class="pln"> click over icon script</span><span class="pun">.</span><span class="pln">
</span><span class="pun">::</span><span class="pln"> </span><span class="typ">Windows</span><span class="pln"> </span><span class="lit">10</span><span class="pln"> version </span><span class="lit">1511</span><span class="pln"> </span><span class="pun">(</span><span class="pln">build number </span><span class="lit">10586</span><span class="pun">)</span><span class="pln"> onward
</span><span class="pun">::</span><span class="pln">
</span><span class="pun">::</span><span class="pln"> history</span><span class="pun">:</span><span class="pln">
</span><span class="pun">::</span><span class="pln"> </span><span class="lit">10</span><span class="pun">/</span><span class="lit">08</span><span class="pun">/</span><span class="lit">2022</span><span class="pln"> </span><span class="lit">0.1</span><span class="pun">.</span><span class="lit">4.2</span><span class="pln"> BETA added some stuff </span><span class="kwd">for</span><span class="pln"> taking correct ownership </span><span class="kwd">with</span><span class="pln"> different languages
</span><span class="pun">::</span><span class="pln"> </span><span class="lit">10</span><span class="pun">/</span><span class="lit">08</span><span class="pun">/</span><span class="lit">2022</span><span class="pln"> </span><span class="lit">0.1</span><span class="pun">.</span><span class="lit">4.1</span><span class="pln"> BETA added some hints to take ownership
</span><span class="pun">::</span><span class="pln"> </span><span class="lit">04</span><span class="pun">/</span><span class="lit">02</span><span class="pun">/</span><span class="lit">2022</span><span class="pln"> </span><span class="lit">0.1</span><span class="pun">.</span><span class="lit">4</span><span class="pln"> BETA fix some minor bug </span><span class="kwd">and</span><span class="pln"> aesthetic improvements
</span><span class="pun">::</span><span class="pln"> </span><span class="str">/10/</span><span class="lit">2021</span><span class="pln"> </span><span class="lit">0.1</span><span class="pun">.</span><span class="lit">4</span><span class="pln"> BETA fix bug </span><span class="kwd">for</span><span class="pln"> elevated </span><span class="kwd">char</span><span class="pln"> </span><span class="pun">;,=()</span><span class="pln"> </span><span class="pun">&^</span><span class="pln">
</span><span class="pun">::</span><span class="pln"> </span><span class="lit">29</span><span class="pun">/</span><span class="lit">09</span><span class="pun">/</span><span class="lit">2021</span><span class="pln"> </span><span class="lit">0.1</span><span class="pun">.</span><span class="lit">3</span><span class="pln"> BETA </span><span class="typ">Search</span><span class="pln"> </span><span class="kwd">for</span><span class="pln"> applications that </span><span class="kwd">do</span><span class="pln"> </span><span class="kwd">not</span><span class="pln"> have </span><span class="typ">InstallLocation</span><span class="pln"> </span><span class="kwd">set</span><span class="pun">.</span><span class="pln">
</span><span class="pun">::</span><span class="pln"> </span><span class="typ">Enable</span><span class="pln"> support </span><span class="kwd">for</span><span class="pln"> </span><span class="typ">Unicode</span><span class="pln"> UTF</span><span class="pun">-</span><span class="lit">8</span><span class="pln"> </span><span class="kwd">and</span><span class="pln"> VT</span><span class="pun">-</span><span class="pln">ANSI
</span><span class="pun">::</span><span class="pln"> </span><span class="lit">25</span><span class="pun">/</span><span class="lit">09</span><span class="pun">/</span><span class="lit">2021</span><span class="pln"> </span><span class="lit">0.1</span><span class="pun">.</span><span class="lit">2</span><span class="pln"> BETA removed debug</span><span class="pun">,</span><span class="pln"> added run </span><span class="kwd">as</span><span class="pln"> administrator </span><span class="pun">,</span><span class="pln"> thanks </span><span class="typ">Matthew</span><span class="pln"> </span><span class="typ">Wai</span><span class="pln">
</span><span class="pun">::</span><span class="pln"> </span><span class="lit">25</span><span class="pun">/</span><span class="lit">09</span><span class="pun">/</span><span class="lit">2021</span><span class="pln"> </span><span class="lit">0.1</span><span class="pun">.</span><span class="lit">1</span><span class="pln"> BETA </span><span class="kwd">add</span><span class="pln"> debug instruction </span><span class="kwd">for</span><span class="pln"> </span><span class="str">"file not found"</span><span class="pln"> bug</span><span class="pun">/</span><span class="pln">error</span><span class="pun">.</span><span class="pln">
</span><span class="pun">::</span><span class="pln">
</span><span class="pun">::</span><span class="pln"> </span><span class="kwd">ref</span><span class="pun">:</span><span class="pln"> https</span><span class="pun">:</span><span class="com">//www.tenforums.com/tutorials/4689-uninstall-apps-windows-10-a.html</span><span class="pln">
</span><span class="pun">::</span><span class="pln"> </span><span class="kwd">ref</span><span class="pun">:</span><span class="pln"> https</span><span class="pun">:</span><span class="com">//docs.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences</span><span class="pln">
</span><span class="pun">::</span><span class="pln">
</span><span class="pun">::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::</span><span class="pln">
</span><span class="lit">@echo</span><span class="pln"> off </span><span class="pun">&</span><span class="pln"> setlocal </span><span class="typ">EnableDelayedExpansion</span><span class="pun">&</span><span class="pln">color </span><span class="lit">1f</span><span class="pun">&</span><span class="pln">title </span><span class="typ">CleanWA</span><span class="pln"> </span><span class="pun">%</span><span class="typ">Version</span><span class="pun">%</span><span class="pln">
</span><span class="typ">Rem</span><span class="pln"> </span><span class="typ">Choice</span><span class="pln"> the </span><span class="typ">WindowsApps</span><span class="pln"> </span><span class="pun">(</span><span class="pln">WA</span><span class="pun">)</span><span class="pln"> directory to check</span><span class="pun">.</span><span class="pln">
</span><span class="kwd">set</span><span class="pln"> </span><span class="str">"WA=%ProgramW6432%\WindowsApps"</span><span class="pln">
</span><span class="kwd">set</span><span class="pln"> </span><span class="typ">PromptLine</span><span class="pun">=</span><span class="pln">
copy </span><span class="pun">/</span><span class="pln">y nul </span><span class="str">"%TEMP%\yesnoall#.tmp"</span><span class="pln"> </span><span class="pun">></span><span class="pln">nul
</span><span class="kwd">for</span><span class="pln"> </span><span class="pun">/</span><span class="pln">f </span><span class="str">"tokens=2* delims=#"</span><span class="pln"> </span><span class="pun">%%</span><span class="pln">A </span><span class="kwd">in</span><span class="pln"> </span><span class="pun">(</span><span class="pln"> </span><span class="str">'^<nul copy /-y nul "%TEMP%\yesnoall#.tmp"'</span><span class="pln">
</span><span class="pun">)</span><span class="pln"> </span><span class="kwd">do</span><span class="pln"> </span><span class="kwd">set</span><span class="pln"> </span><span class="typ">PromptLine</span><span class="pun">=%%</span><span class="pln">A
</span><span class="kwd">del</span><span class="pln"> </span><span class="str">"%TEMP%\yesnoall#.tmp"</span><span class="pln">
</span><span class="kwd">set</span><span class="pln"> </span><span class="typ">PromptLine</span><span class="pun">=%</span><span class="typ">PromptLine</span><span class="pun">:</span><span class="pln"> </span><span class="pun">=%&</span><span class="pln"> rem </span><span class="kwd">delete</span><span class="pln"> spaces </span><span class="pun">(</span><span class="kwd">for</span><span class="pln"> russian</span><span class="pun">)</span><span class="pln">
</span><span class="kwd">for</span><span class="pln"> </span><span class="pun">/</span><span class="pln">f </span><span class="str">"tokens=2-7 delims=[(/)]"</span><span class="pln"> </span><span class="pun">%%</span><span class="pln">A </span><span class="kwd">in</span><span class="pln"> </span><span class="pun">(</span><span class="pln"> </span><span class="str">"%PromptLine%"</span><span class="pln">
</span><span class="pun">)</span><span class="pln"> </span><span class="kwd">do</span><span class="pln"> </span><span class="kwd">if</span><span class="pln"> </span><span class="str">"%%~E"</span><span class="pln"> </span><span class="pun">==</span><span class="pln"> </span><span class="str">""</span><span class="pln"> </span><span class="pun">(</span><span class="pln"> </span><span class="kwd">set</span><span class="pln"> ans_yes</span><span class="pun">=%%</span><span class="pln">A</span><span class="pun">&</span><span class="pln"> </span><span class="kwd">set</span><span class="pln"> ans_no</span><span class="pun">=%%</span><span class="pln">B</span><span class="pun">&</span><span class="pln"> </span><span class="kwd">set</span><span class="pln"> ans_all</span><span class="pun">=%%</span><span class="pln">C
</span><span class="pun">)</span><span class="pln"> </span><span class="kwd">else</span><span class="pln"> </span><span class="pun">(</span><span class="pln"> </span><span class="kwd">set</span><span class="pln"> ans_yes</span><span class="pun">=%%</span><span class="pln">A</span><span class="pun">&</span><span class="pln"> </span><span class="kwd">set</span><span class="pln"> ans_no</span><span class="pun">=%%</span><span class="pln">C</span><span class="pun">&</span><span class="pln"> </span><span class="kwd">set</span><span class="pln"> ans_all</span><span class="pun">=%%</span><span class="pln">E
</span><span class="pun">)</span><span class="pln">
</span><span class="kwd">set</span><span class="pln"> ans_y</span><span class="pun">=%</span><span class="pln">ans_yes</span><span class="pun">:~</span><span class="lit">0</span><span class="pun">,</span><span class="lit">1</span><span class="pun">%&</span><span class="pln"> </span><span class="kwd">set</span><span class="pln"> ans_n</span><span class="pun">=%</span><span class="pln">ans_no</span><span class="pun">:~</span><span class="lit">0</span><span class="pun">,</span><span class="lit">1</span><span class="pun">%&</span><span class="pln"> </span><span class="kwd">set</span><span class="pln"> ans_a</span><span class="pun">=%</span><span class="pln">ans_all</span><span class="pun">:~</span><span class="lit">0</span><span class="pun">,</span><span class="lit">1</span><span class="pun">%</span><span class="pln">
echo </span><span class="pun">%</span><span class="pln">ans_yes</span><span class="pun">%,</span><span class="pln"> </span><span class="pun">%</span><span class="pln">ans_no</span><span class="pun">%,</span><span class="pln"> </span><span class="pun">%</span><span class="pln">ans_all</span><span class="pun">%</span><span class="pln">
echo </span><span class="pun">%</span><span class="pln">ans_y</span><span class="pun">%,</span><span class="pln"> </span><span class="pun">%</span><span class="pln">ans_n</span><span class="pun">%,</span><span class="pln"> </span><span class="pun">%</span><span class="pln">ans_a</span><span class="pun">%</span><span class="pln">
</span><span class="typ">Rem</span><span class="pln"> </span><span class="typ">Check</span><span class="pln"> </span><span class="kwd">for</span><span class="pln"> </span><span class="typ">Run</span><span class="pln"> </span><span class="kwd">as</span><span class="pln"> administrator</span><span class="pun">.</span><span class="pln">
call </span><span class="pun">:</span><span class="typ">Restart_as_Administrator</span><span class="pln"> </span><span class="pun">%</span><span class="lit">1</span><span class="pln">
</span><span class="typ">Call</span><span class="pln"> </span><span class="pun">:</span><span class="pln">video_setting
</span><span class="typ">Rem</span><span class="pln"> check </span><span class="kwd">for</span><span class="pln"> permission on WA
</span><span class="kwd">if</span><span class="pln"> </span><span class="kwd">not</span><span class="pln"> exist </span><span class="str">"%WA%\."</span><span class="pln"> echo</span><span class="pun">(</span><span class="pln"> </span><span class="pun">&</span><span class="pln"> echo </span><span class="typ">Error</span><span class="pun">:</span><span class="pln"> </span><span class="typ">Problem</span><span class="pln"> accessing </span><span class="str">"%WA%"</span><span class="pln"> </span><span class="pun">&</span><span class="pln"> </span><span class="kwd">goto</span><span class="pln"> </span><span class="pun">:</span><span class="pln">the_end
echo</span><span class="pun">(</span><span class="pln">
echo </span><span class="pun">•</span><span class="pln"> </span><span class="typ">Analyze</span><span class="pln"> </span><span class="str">"%WA%"</span><span class="pln">
echo</span><span class="pun">(</span><span class="pln">
</span><span class="typ">Echo</span><span class="pln"> </span><span class="pun">•</span><span class="pln"> </span><span class="typ">Check</span><span class="pln"> </span><span class="kwd">for</span><span class="pln"> applications that </span><span class="kwd">do</span><span class="pln"> </span><span class="kwd">not</span><span class="pln"> have </span><span class="str">"InstallLocation"</span><span class="pln"> </span><span class="kwd">set</span><span class="pun">.</span><span class="pln">
echo</span><span class="pun">(</span><span class="pln">
rem create list </span><span class="kwd">of</span><span class="pln"> registered app
</span><span class="pun">></span><span class="pln"> </span><span class="str">"%tmp%\CleanWA.RegisteredApps.tmp.txt"</span><span class="pln"> </span><span class="pun">^</span><span class="pln">
</span><span class="pun">(</span><span class="pln">
rem exclude </span><span class="str">"system"</span><span class="pln"> applications </span><span class="kwd">in</span><span class="pln"> c</span><span class="pun">:</span><span class="pln">\windows folder
powershell </span><span class="pun">-</span><span class="typ">Command</span><span class="pln"> </span><span class="str">"Get-AppxPackage -AllUsers | ? { $_.SignatureKind -ne 'System' } | sort -property {$_.InstallLocation+' '} | ForEach-Object {'{0,-40} {1,-20} {2}' -f $_.name,$_.version,$_.InstallLocation}"</span><span class="pln">
</span><span class="pun">)</span><span class="pln">
type nul</span><span class="pun">:</span><span class="pln"> </span><span class="pun">></span><span class="pln"> </span><span class="str">"%tmp%\CleanWA.RegisteredApps_good.tmp.txt"</span><span class="pln">
type nul</span><span class="pun">:</span><span class="pln"> </span><span class="pun">></span><span class="pln"> </span><span class="str">"%tmp%\CleanWA.RegisteredApps_NO_good.tmp.txt"</span><span class="pln">
FOR </span><span class="pun">/</span><span class="pln">f </span><span class="str">"usebackq tokens=1,2,*"</span><span class="pln"> </span><span class="pun">%%</span><span class="pln">a </span><span class="kwd">in</span><span class="pln"> </span><span class="pun">(</span><span class="str">"%tmp%\CleanWA.RegisteredApps.tmp.txt"</span><span class="pun">)</span><span class="pln"> </span><span class="kwd">do</span><span class="pln"> </span><span class="pun">(</span><span class="pln">
</span><span class="kwd">if</span><span class="pln"> </span><span class="str">"%%c"</span><span class="pln"> equ </span><span class="str">""</span><span class="pln"> </span><span class="pun">(</span><span class="pln">
echo</span><span class="pun">(</span><span class="pln"> </span><span class="pun">%</span><span class="pln">CSI</span><span class="pun">%</span><span class="lit">7m</span><span class="pun">?</span><span class="pln"> </span><span class="typ">Warning</span><span class="pun">:</span><span class="pln"> </span><span class="typ">Registered</span><span class="pln"> app </span><span class="str">"%%a"</span><span class="pln"> does </span><span class="kwd">not</span><span class="pln"> have a </span><span class="str">"InstallLocation"</span><span class="pln"> </span><span class="kwd">set</span><span class="pun">/</span><span class="kwd">defined</span><span class="pun">.</span><span class="pln"> </span><span class="pun">?%</span><span class="pln">CSI</span><span class="pun">%</span><span class="lit">27m</span><span class="pln">
echo</span><span class="pun">(</span><span class="pln">
echo </span><span class="typ">Rem</span><span class="pln"> </span><span class="typ">Warning</span><span class="pun">:</span><span class="pln"> </span><span class="typ">Registered</span><span class="pln"> app </span><span class="str">"%%a"</span><span class="pln"> does </span><span class="kwd">not</span><span class="pln"> have a </span><span class="str">"InstallLocation"</span><span class="pln"> </span><span class="kwd">set</span><span class="pun">/</span><span class="kwd">defined</span><span class="pun">.</span><span class="pln"> </span><span class="pun">>></span><span class="pln"> </span><span class="str">"%tmp%\CleanWA.RegisteredApps_NO_good.tmp.txt"</span><span class="pln">
</span><span class="pun">)</span><span class="pln"> </span><span class="kwd">else</span><span class="pln"> echo</span><span class="pun">(%%</span><span class="pln">a </span><span class="pun">%%</span><span class="pln">b </span><span class="pun">%%</span><span class="pln">c </span><span class="pun">>></span><span class="pln"> </span><span class="str">"%tmp%\CleanWA.RegisteredApps_good.tmp.txt"</span><span class="pln">
</span><span class="pun">)</span><span class="pln">
echo v check finished</span><span class="pun">.</span><span class="pln">
echo</span><span class="pun">(</span><span class="pln">
echo </span><span class="pun">•</span><span class="pln"> </span><span class="typ">Detect</span><span class="pln"> orphaned dirs
echo</span><span class="pun">(</span><span class="pln">
type nul </span><span class="pun">></span><span class="pln"> </span><span class="str">"%tmp%\CleanWA.report_orphans.tmp.txt"</span><span class="pln">
</span><span class="kwd">set</span><span class="pln"> </span><span class="str">"dn=0"</span><span class="pln"> </span><span class="pun">&</span><span class="pln"> rem number </span><span class="kwd">of</span><span class="pln"> folders</span><span class="pun">/</span><span class="pln">directories
</span><span class="kwd">set</span><span class="pln"> </span><span class="pun">/</span><span class="pln">A </span><span class="str">"Size=0, Totsize=0,dirsO"</span><span class="pln">
FOR </span><span class="pun">/</span><span class="pln">f </span><span class="str">"tokens=*"</span><span class="pln"> </span><span class="pun">%%</span><span class="pln">z IN </span><span class="pun">(</span><span class="str">'dir /b /o:n "%WA%"'</span><span class="pun">)</span><span class="pln"> DO </span><span class="pun">(</span><span class="pln">
</span><span class="kwd">set</span><span class="pln"> </span><span class="pun">/</span><span class="pln">a </span><span class="str">"dn+=1"</span><span class="pln">
FOR </span><span class="pun">/</span><span class="pln">f </span><span class="str">"tokens=1-4"</span><span class="pln"> </span><span class="pun">%%</span><span class="pln">g </span><span class="kwd">in</span><span class="pln"> </span><span class="pun">(</span><span class="str">'dir /S /W /-C "%WA%\%%z"'</span><span class="pun">)</span><span class="pln"> </span><span class="kwd">do</span><span class="pln"> </span><span class="pun">(</span><span class="kwd">set</span><span class="pln"> </span><span class="str">"oldlineSize=!line!"</span><span class="pln"> </span><span class="pun">&</span><span class="pln"> </span><span class="kwd">set</span><span class="pln"> line</span><span class="pun">=%%</span><span class="pln">i</span><span class="pun">)</span><span class="pln">
call </span><span class="pun">:</span><span class="pln">pad dn </span><span class="lit">4</span><span class="pln">
</span><span class="kwd">set</span><span class="pln"> </span><span class="pun">/</span><span class="pln">A </span><span class="str">"size=!oldlineSize:~0,-4!+0, sizeMB=size/105"</span><span class="pln">
echo </span><span class="pun">•</span><span class="pln"> </span><span class="pun">!</span><span class="pln">dn</span><span class="pun">!</span><span class="pln"> </span><span class="pun">-</span><span class="pln"> </span><span class="typ">Searching</span><span class="pln"> </span><span class="kwd">for</span><span class="pln"> folder</span><span class="pun">:</span><span class="pln">
echo </span><span class="str">"%%z"</span><span class="pln"> </span><span class="pun">(</span><span class="pln">about </span><span class="pun">!</span><span class="typ">SizeMB</span><span class="pun">!</span><span class="pln"> </span><span class="typ">MBytes</span><span class="pun">^)</span><span class="pln"> </span><span class="pun">%</span><span class="pln">CSI</span><span class="pun">%</span><span class="lit">0K</span><span class="pln">
</span><span class="kwd">set</span><span class="pln"> </span><span class="str">"found="</span><span class="pln">
</span><span class="kwd">for</span><span class="pln"> </span><span class="pun">/</span><span class="pln">f </span><span class="str">"usebackq tokens=1,2,*"</span><span class="pln"> </span><span class="pun">%%</span><span class="pln">a </span><span class="kwd">in</span><span class="pln"> </span><span class="pun">(</span><span class="str">"%tmp%\CleanWA.RegisteredApps_good.tmp.txt"</span><span class="pun">)</span><span class="pln"> </span><span class="kwd">do</span><span class="pln"> </span><span class="kwd">if</span><span class="pln"> </span><span class="kwd">not</span><span class="pln"> </span><span class="kwd">defined</span><span class="pln"> found </span><span class="pun">(</span><span class="pln">
rem echo </span><span class="pun">•</span><span class="pln"> </span><span class="typ">Pkg</span><span class="pun">.</span><span class="pln"> </span><span class="typ">InstallLocation</span><span class="pln"> </span><span class="str">"%%c"</span><span class="pln"> </span><span class="pun">%</span><span class="pln">CSI</span><span class="pun">%</span><span class="lit">0K</span><span class="pln"> </span><span class="pun">%</span><span class="pln">RI</span><span class="pun">%</span><span class="pln">
</span><span class="kwd">set</span><span class="pln"> _V_</span><span class="pun">=%%</span><span class="pln">z
</span><span class="kwd">set</span><span class="pln"> v1</span><span class="pun">=</span><span class="str">"x!_V_:%%a_%%b=!x"</span><span class="pln">
</span><span class="kwd">set</span><span class="pln"> v2</span><span class="pun">=</span><span class="str">"x!_V_!x"</span><span class="pln">
</span><span class="kwd">if</span><span class="pln"> </span><span class="pun">!</span><span class="pln">v1</span><span class="pun">!</span><span class="pln"> NEQ </span><span class="pun">!</span><span class="pln">v2</span><span class="pun">!</span><span class="pln"> </span><span class="pun">(</span><span class="pln">
</span><span class="kwd">set</span><span class="pln"> </span><span class="typ">Found</span><span class="pun">=</span><span class="lit">1</span><span class="pln">
rem echo</span><span class="pun">(</span><span class="pln"> </span><span class="pun">%</span><span class="pln">CSI</span><span class="pun">%</span><span class="lit">102m</span><span class="pun">?</span><span class="pln"> </span><span class="typ">Found</span><span class="pln"> an app that </span><span class="kwd">use</span><span class="pln"> </span><span class="kwd">this</span><span class="pln"> folder </span><span class="pun">?%</span><span class="pln">CSI</span><span class="pun">%</span><span class="lit">44m</span><span class="pln"> </span><span class="pun">:</span><span class="pln"> </span><span class="pun">%</span><span class="pln">CSI</span><span class="pun">%</span><span class="lit">102m</span><span class="str">"%%a"</span><span class="pun">%</span><span class="pln">CSI</span><span class="pun">%</span><span class="lit">44m</span><span class="pln"> version</span><span class="pun">:</span><span class="pln"> </span><span class="str">"%%b"</span><span class="pln"> </span><span class="pun">%</span><span class="pln">CSI</span><span class="pun">%</span><span class="lit">0K</span><span class="pln">
</span><span class="pun">)</span><span class="pln">
</span><span class="pun">)</span><span class="pln">
</span><span class="kwd">if</span><span class="pln"> </span><span class="kwd">defined</span><span class="pln"> found </span><span class="pun">(</span><span class="pln">
echo</span><span class="pun">(%</span><span class="pln">RI</span><span class="pun">%%</span><span class="pln">RI</span><span class="pun">%%</span><span class="pln">RI</span><span class="pun">%</span><span class="pln">
</span><span class="pun">)</span><span class="pln"> </span><span class="kwd">else</span><span class="pln"> </span><span class="pun">(</span><span class="pln">
rem check </span><span class="kwd">for</span><span class="pln"> unknown folder</span><span class="pun">/</span><span class="pln">dir
rem known</span><span class="pun">:</span><span class="pln">_x64_</span><span class="pun">,</span><span class="pln"> _x86_</span><span class="pun">,</span><span class="pln"> _neutral_ </span><span class="pun">....</span><span class="pln"> others</span><span class="pun">?</span><span class="pln">
</span><span class="kwd">set</span><span class="pln"> v1</span><span class="pun">=</span><span class="str">"x!_V_:_x64_=!x"</span><span class="pln">
</span><span class="kwd">set</span><span class="pln"> v2</span><span class="pun">=</span><span class="str">"x!_V_!x"</span><span class="pln">
</span><span class="kwd">set</span><span class="pln"> </span><span class="str">"OK=N"</span><span class="pln">
</span><span class="kwd">if</span><span class="pln"> </span><span class="pun">!</span><span class="pln">v1</span><span class="pun">!</span><span class="pln"> NEQ </span><span class="pun">!</span><span class="pln">v2</span><span class="pun">!</span><span class="pln"> </span><span class="kwd">set</span><span class="pln"> </span><span class="str">"OK=Y"</span><span class="pln">
</span><span class="kwd">set</span><span class="pln"> v1</span><span class="pun">=</span><span class="str">"x!_V_:_x86_=!x"</span><span class="pln">
</span><span class="kwd">if</span><span class="pln"> </span><span class="pun">!</span><span class="pln">v1</span><span class="pun">!</span><span class="pln"> NEQ </span><span class="pun">!</span><span class="pln">v2</span><span class="pun">!</span><span class="pln"> </span><span class="kwd">set</span><span class="pln"> </span><span class="str">"OK=Y"</span><span class="pln">
</span><span class="kwd">set</span><span class="pln"> v1</span><span class="pun">=</span><span class="str">"x!_V_:_neutral_=!x"</span><span class="pln">
</span><span class="kwd">if</span><span class="pln"> </span><span class="pun">!</span><span class="pln">v1</span><span class="pun">!</span><span class="pln"> NEQ </span><span class="pun">!</span><span class="pln">v2</span><span class="pun">!</span><span class="pln"> </span><span class="kwd">set</span><span class="pln"> </span><span class="str">"OK=Y"</span><span class="pln">
</span><span class="kwd">if</span><span class="pln"> </span><span class="pun">!</span><span class="pln">OK</span><span class="pun">!</span><span class="pln"> NEQ Y </span><span class="pun">(</span><span class="pln">
echo</span><span class="pun">(</span><span class="pln">
echo </span><span class="pun">%</span><span class="pln">CSI</span><span class="pun">%</span><span class="lit">43m</span><span class="pun">?</span><span class="pln"> </span><span class="typ">No</span><span class="pln"> </span><span class="typ">Match</span><span class="pln"> folder</span><span class="pun">:</span><span class="pln"> </span><span class="str">"%%z"</span><span class="pln"> </span><span class="pun">?%</span><span class="pln">CSI</span><span class="pun">%</span><span class="lit">44m</span><span class="pun">%</span><span class="pln">CSI</span><span class="pun">%</span><span class="lit">0K</span><span class="pln">
echo</span><span class="pun">(</span><span class="pln">
echo</span><span class="pun">(</span><span class="pln">
ping </span><span class="pun">-</span><span class="pln">n </span><span class="lit">2</span><span class="pln"> </span><span class="lit">127.0</span><span class="pun">.</span><span class="lit">0.1</span><span class="pln"> </span><span class="pun">></span><span class="pln">nul
</span><span class="pun">)</span><span class="pln"> </span><span class="kwd">else</span><span class="pln"> </span><span class="pun">(</span><span class="pln">
echo</span><span class="pun">(</span><span class="pln">
echo </span><span class="pun">%</span><span class="pln">CSI</span><span class="pun">%</span><span class="lit">101m</span><span class="pun">?</span><span class="pln"> orphans folder</span><span class="pun">!</span><span class="pln"> </span><span class="pun">?%</span><span class="pln">CSI</span><span class="pun">%</span><span class="lit">44m</span><span class="pun">%</span><span class="pln">CSI</span><span class="pun">%</span><span class="lit">0K</span><span class="pln">
echo</span><span class="pun">(</span><span class="pln">
echo</span><span class="pun">(</span><span class="pln">
rem why </span><span class="lit">105</span><span class="pun">?</span><span class="pln"> </span><span class="lit">1024</span><span class="pun">*</span><span class="lit">1024</span><span class="pun">/</span><span class="lit">10000</span><span class="pln"> </span><span class="pun">~</span><span class="pln"> </span><span class="lit">105</span><span class="pln">
</span><span class="kwd">set</span><span class="pln"> </span><span class="pun">/</span><span class="pln">A </span><span class="str">"Totsize+=size, TotsizeMB=Totsize/105, dirsOrphans+=1"</span><span class="pln">
title </span><span class="typ">CleanWA</span><span class="pln"> </span><span class="pun">%</span><span class="typ">Version</span><span class="pun">%</span><span class="pln"> </span><span class="pun">[</span><span class="typ">Tot</span><span class="pun">.</span><span class="pln"> space orphans</span><span class="pun">:</span><span class="pln"> about </span><span class="pun">!</span><span class="typ">TotsizeMB</span><span class="pun">!</span><span class="pln"> MB</span><span class="pun">]</span><span class="pln"> </span><span class="pun">[</span><span class="pln">dirs</span><span class="pun">/</span><span class="pln">folder orphans</span><span class="pun">:</span><span class="pln"> </span><span class="pun">!</span><span class="pln">dirsOrphans</span><span class="pun">!]</span><span class="pln">
</span><span class="pun">(</span><span class="pln">
echo rem folder </span><span class="str">"%%z"</span><span class="pln"> </span><span class="pun">(</span><span class="pln">about </span><span class="pun">!</span><span class="pln">oldlineSize</span><span class="pun">!</span><span class="pln"> </span><span class="typ">Bytes</span><span class="pun">^,</span><span class="pln"> about </span><span class="pun">!</span><span class="typ">SizeMB</span><span class="pun">!</span><span class="pln"> </span><span class="typ">MBytes</span><span class="pun">^)</span><span class="pln">
echo takeown </span><span class="pun">/</span><span class="pln">F </span><span class="str">"%WA%\%%z"</span><span class="pln"> </span><span class="pun">/</span><span class="pln">r </span><span class="pun">/</span><span class="pln">d </span><span class="pun">%</span><span class="pln">ans_y</span><span class="pun">%</span><span class="pln">
echo icacls </span><span class="str">"%WA%\%%z"</span><span class="pln"> </span><span class="pun">/</span><span class="pln">t </span><span class="pun">/</span><span class="pln">grant </span><span class="pun">%</span><span class="pln">USERNAME</span><span class="pun">%:</span><span class="pln">F
echo RD </span><span class="pun">/</span><span class="pln">Q </span><span class="pun">/</span><span class="pln">S </span><span class="str">"%WA%\%%z"</span><span class="pln">
echo</span><span class="pun">(</span><span class="pln">
</span><span class="pun">)</span><span class="pln"> </span><span class="pun">>></span><span class="pln"> </span><span class="str">"%tmp%\CleanWA.report_orphans.tmp.txt"</span><span class="pln">
</span><span class="pun">)</span><span class="pln">
</span><span class="pun">)</span><span class="pln">
rem pathping </span><span class="lit">127.0</span><span class="pun">.</span><span class="lit">0.1</span><span class="pln"> </span><span class="pun">-</span><span class="pln">n </span><span class="pun">-</span><span class="pln">q </span><span class="lit">1</span><span class="pln"> </span><span class="pun">-</span><span class="pln">p </span><span class="lit">100</span><span class="pln"> </span><span class="pun">></span><span class="pln">nul
</span><span class="pun">)</span><span class="pln">
echo</span><span class="pun">(</span><span class="pln">
echo</span><span class="pun">(</span><span class="pln">
echo</span><span class="pun">(</span><span class="pln">
echo v check finished</span><span class="pun">.</span><span class="pln">
echo</span><span class="pun">(</span><span class="pln">
echo dirs</span><span class="pun">/</span><span class="pln">folder orphans</span><span class="pun">:</span><span class="pln"> </span><span class="pun">!</span><span class="pln">dirsOrphans</span><span class="pun">!</span><span class="pln">
echo</span><span class="pun">(</span><span class="pln">
echo </span><span class="typ">Tot</span><span class="pun">.</span><span class="pln"> space orphans</span><span class="pun">:</span><span class="pln"> about </span><span class="pun">!</span><span class="typ">TotsizeMB</span><span class="pun">!</span><span class="pln"> MB
echo</span><span class="pun">(</span><span class="pln">
</span><span class="pun">></span><span class="pln">nul</span><span class="pun">:</span><span class="pln"> copy </span><span class="pun">/</span><span class="pln">a </span><span class="str">"%tmp%\CleanWA.RegisteredApps_NO_good.tmp.txt"</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> </span><span class="pun">/</span><span class="pln">a </span><span class="str">"%tmp%\CleanWA.report_orphans.tmp.txt"</span><span class="pln"> </span><span class="str">"%tmp%\CleanWA.report.tmp.txt"</span><span class="pln">
echo coping </span><span class="typ">Report</span><span class="pun">/</span><span class="pln">script </span><span class="str">"%tmp%\CleanWA.report.tmp.txt"</span><span class="pln"> </span><span class="kwd">for</span><span class="pln"> offline </span><span class="kwd">delete</span><span class="pln"> </span><span class="kwd">in</span><span class="pln"> \Users\Public
copy </span><span class="str">"%tmp%\CleanWA.report.tmp.txt"</span><span class="pln"> \Users\Public
echo</span><span class="pun">(</span><span class="pln">
pause
start notepad </span><span class="str">"\Users\Public\CleanWA.report.tmp.txt"</span><span class="pln">
</span><span class="pun">:</span><span class="pln">the_end
</span><span class="pun">::</span><span class="pln"> pause </span><span class="kwd">if</span><span class="pln"> </span><span class="kwd">double</span><span class="pln"> clicked on instead </span><span class="kwd">of</span><span class="pln"> run </span><span class="kwd">from</span><span class="pln"> command line</span><span class="pun">.</span><span class="pln">
echo </span><span class="pun">%</span><span class="pln">cmdcmdline</span><span class="pun">%</span><span class="pln"> </span><span class="pun">|</span><span class="pln"> findstr </span><span class="pun">/</span><span class="pln">I </span><span class="pun">/</span><span class="pln">L </span><span class="pun">%</span><span class="pln">comspec</span><span class="pun">%</span><span class="pln"> </span><span class="pun">></span><span class="pln">nul </span><span class="lit">2</span><span class="pun">>&</span><span class="lit">1</span><span class="pln">
</span><span class="kwd">if</span><span class="pln"> </span><span class="pun">%</span><span class="pln">errorlevel</span><span class="pun">%</span><span class="pln"> </span><span class="pun">==</span><span class="pln"> </span><span class="lit">0</span><span class="pln"> echo</span><span class="pun">(</span><span class="pln"> </span><span class="pun">&</span><span class="pln"> pause
</span><span class="kwd">exit</span><span class="pln"> </span><span class="pun">/</span><span class="pln">B </span><span class="lit">0</span><span class="pln">
</span><span class="kwd">goto</span><span class="pln"> </span><span class="pun">:</span><span class="pln">eof
</span><span class="pun">::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::</span><span class="pln">
</span><span class="pun">::::::::::::::::::::::::::::::::::</span><span class="pln"> SUBROUTINE </span><span class="pun">::::::::::::::::::::::::::::::</span><span class="pln">
</span><span class="pun">::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::</span><span class="pln">
</span><span class="pun">:</span><span class="typ">Restart_as_Administrator</span><span class="pln">
</span><span class="pun">(</span><span class="typ">Fsutil</span><span class="pln"> </span><span class="typ">Dirty</span><span class="pln"> </span><span class="typ">Query</span><span class="pln"> </span><span class="pun">%</span><span class="typ">SystemDrive</span><span class="pun">%></span><span class="typ">Nul</span><span class="pun">)&&(</span><span class="pln">
</span><span class="kwd">if</span><span class="pln"> </span><span class="str">"%1"</span><span class="pln"> neq </span><span class="str">"admin"</span><span class="pln"> </span><span class="pun">(</span><span class="pln">
start </span><span class="pun">/</span><span class="pln">MAX </span><span class="pun">%~</span><span class="pln">f0 admin
</span><span class="typ">Exit</span><span class="pln">
</span><span class="pun">)</span><span class="pln">
</span><span class="pun">)||(</span><span class="pln">
mode con cols</span><span class="pun">=</span><span class="lit">90</span><span class="pln"> lines</span><span class="pun">=</span><span class="lit">20</span><span class="pln">
echo</span><span class="pun">(</span><span class="pln"> </span><span class="pun">&</span><span class="pln"> echo </span><span class="typ">It</span><span class="pln"> </span><span class="kwd">is</span><span class="pln"> necessary to start the script </span><span class="kwd">with</span><span class="pln"> administrative rights</span><span class="pun">.</span><span class="pln">
echo</span><span class="pun">(</span><span class="pln"> </span><span class="pun">&</span><span class="pln"> echo </span><span class="typ">Please</span><span class="pln"> wait </span><span class="pun">...</span><span class="pln"> I am restarting the script </span><span class="kwd">with</span><span class="pln"> administrative rights</span><span class="pun">.</span><span class="pln">
echo</span><span class="pun">(</span><span class="pln"> </span><span class="pun">&</span><span class="pln"> echo </span><span class="typ">Answer</span><span class="pln"> </span><span class="str">"YES"</span><span class="pln"> to the </span><span class="kwd">next</span><span class="pln"> </span><span class="typ">User</span><span class="pln"> </span><span class="typ">Account</span><span class="pln"> </span><span class="typ">Control</span><span class="pln"> UAC request to </span><span class="kwd">continue</span><span class="pln">
echo</span><span class="pun">(</span><span class="pln"> running </span><span class="kwd">this</span><span class="pln"> script </span><span class="kwd">with</span><span class="pln"> administrative permissions</span><span class="pun">.</span><span class="pln"> </span><span class="pun">&</span><span class="pln"> echo</span><span class="pun">(</span><span class="pln">
timeout </span><span class="pun">/</span><span class="pln">t </span><span class="lit">4</span><span class="pln">
powershell</span><span class="pun">.</span><span class="pln">exe </span><span class="pun">-</span><span class="pln">c </span><span class="str">"Start -WindowStyle Maximized -Verb RunAs cmd /c, ("</span><span class="pun">^</span><span class="str">""</span><span class="pun">%~</span><span class="pln">f0</span><span class="str">"^"" -replace '[;,=() &^]', '^$0'), "</span><span class="pln">admin</span><span class="str">" "</span><span class="pln"> </span><span class="pun">&</span><span class="pln"> </span><span class="typ">Exit</span><span class="pln">
</span><span class="pun">)</span><span class="pln">
</span><span class="kwd">goto</span><span class="pln"> </span><span class="pun">:</span><span class="pln">eof
</span><span class="pun">::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::</span><span class="pln">
</span><span class="pun">:</span><span class="pln">video_setting
</span><span class="typ">For</span><span class="pln"> </span><span class="pun">/</span><span class="pln">F </span><span class="pun">%%</span><span class="pln">a </span><span class="typ">In</span><span class="pln"> </span><span class="pun">(</span><span class="str">'echo prompt $E^| cmd'</span><span class="pun">)</span><span class="pln"> </span><span class="typ">Do</span><span class="pln"> </span><span class="typ">Set</span><span class="pln"> </span><span class="str">"ESC=%%a"</span><span class="pln">
</span><span class="kwd">set</span><span class="pln"> </span><span class="str">"CSI=%ESC%["</span><span class="pln"> </span><span class="pun">&</span><span class="pln"> </span><span class="kwd">set</span><span class="pln"> </span><span class="str">"RI=%ESC%M"</span><span class="pln">
</span><span class="kwd">set</span><span class="pln"> </span><span class="str">"echoVT=<nul set/p.="</span><span class="pln">
rem </span><span class="kwd">get</span><span class="pln"> windows size
</span><span class="kwd">for</span><span class="pln"> </span><span class="pun">/</span><span class="pln">f </span><span class="str">"tokens=1,2 skip=3"</span><span class="pln"> </span><span class="pun">%%</span><span class="pln">A </span><span class="kwd">in</span><span class="pln"> </span><span class="pun">(</span><span class="str">'powershell -command "$Host.ui.rawui.WindowSize"'</span><span class="pln">
</span><span class="pun">)</span><span class="pln"> </span><span class="kwd">do</span><span class="pln"> </span><span class="kwd">set</span><span class="pln"> </span><span class="pun">/</span><span class="pln">a windowWidth</span><span class="pun">=%%</span><span class="pln">A</span><span class="pun">,</span><span class="pln"> windowHeight</span><span class="pun">=%%</span><span class="pln">B</span><span class="pun">,</span><span class="pln"> sm_e</span><span class="pun">=%%</span><span class="pln">B </span><span class="pun">-</span><span class="pln"> </span><span class="lit">3</span><span class="pln">
mode con</span><span class="pun">:</span><span class="pln"> COLS</span><span class="pun">=%</span><span class="pln">windowWidth</span><span class="pun">%</span><span class="pln"> LINES</span><span class="pun">=%</span><span class="pln">windowHeight</span><span class="pun">%</span><span class="pln">
</span><span class="typ">Rem</span><span class="pln"> </span><span class="typ">Setting</span><span class="pln"> </span><span class="typ">Scrolling</span><span class="pln"> </span><span class="typ">Margins</span><span class="pln">
echo </span><span class="pun">%</span><span class="pln">CSI</span><span class="pun">%</span><span class="lit">4</span><span class="pun">;%</span><span class="pln">sm_e</span><span class="pun">%</span><span class="pln">r
rem </span><span class="kwd">set</span><span class="pln"> UTF</span><span class="pun">-</span><span class="lit">8</span><span class="pln">
chcp </span><span class="lit">65001</span><span class="pln">
cls
</span><span class="kwd">goto</span><span class="pln"> </span><span class="pun">:</span><span class="pln">eof
</span><span class="pun">::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::</span><span class="pln">
</span><span class="pun">:</span><span class="pln">pad
</span><span class="kwd">set</span><span class="pln"> </span><span class="str">"pad=!%1!"</span><span class="pln">
</span><span class="kwd">for</span><span class="pln"> </span><span class="pun">/</span><span class="pln">L </span><span class="pun">%%</span><span class="pln">L </span><span class="kwd">in</span><span class="pln"> </span><span class="pun">(</span><span class="lit">1</span><span class="pun">,</span><span class="lit">1</span><span class="pun">,%</span><span class="lit">2</span><span class="pun">)</span><span class="pln"> </span><span class="kwd">do</span><span class="pln"> </span><span class="kwd">set</span><span class="pln"> </span><span class="str">"pad= !pad!"</span><span class="pln">
</span><span class="kwd">set</span><span class="pln"> </span><span class="str">"pad=!pad:~-%2!"</span><span class="pln">
</span><span class="kwd">set</span><span class="pln"> </span><span class="str">"%1=!pad!"</span><span class="pln">
</span><span class="kwd">goto</span><span class="pln"> </span><span class="pun">:</span><span class="pln">eof
</span><span class="pun">::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::</span></pre><p> </p><p><br /></p>ZorkNikahttp://www.blogger.com/profile/00220798333873847668noreply@blogger.com0tag:blogger.com,1999:blog-5536625962775064923.post-82882265583968270052022-10-08T17:47:00.017+02:002022-12-14T23:10:03.457+01:00Running a vaadin tomcat cluster behind a reverse proxy<p><a href="https://vaadin.com/" target="_blank">Vaadin</a> is full stack java framework to write web applications.</p><p>One of the interesting parts is, that you can write the UI completly in java, so you won't have to mess with different technologies and languages.</p><p>On the other side, it's easy to include webcomponents or write your own and connect them to your java application.</p><p>Vaadin also has a powerfull integrated push system, which allows you to push UI updates/notifications to the client when they are "ready". It's based on athmosphere and can benefit from websockets, but also works/falls back to standard http long polling http requests if nothing else works.</p><p>If you are using a single tomcat / servlet container instance, then you either expose that one to your customers or put some proxy in front of it. It's pretty standard and you find a lot of examples on how to do this with nginx or apache. You can either use plain http+websocket proxy, or (in the case of apache) also the ajp connector to the backend service.<br /></p><p>But if you have multiple backend tomcat / sevlet containers running for redundacy/scaling/... then things get more complicated.</p><p>The vaadin framework is usually statefull, you you just can't route each new request to any one of your backend servers. You will have to always route the requests to the same servlet engine.</p><p>This is called "sticky session", since a session is sticking on the same backend server.</p><p>When you use nginx as the frontend/loadbalancer service, then you will get sticky sessions too, but only based in the ip (and port) of the client. <a href="https://docs.nginx.com/nginx/admin-guide/load-balancer/http-load-balancer/">https://docs.nginx.com/nginx/admin-guide/load-balancer/http-load-balancer/</a></p><p>This works fine as long as you users are spread over the world (or better use different IP addresses), the load is distributed amoung the backend servers.</p><p>But if you have a company application, which is for example used at two locations in the world, with each 50 users, the distribution of the requests can occur to route all to exaclty one of the backend servers and the others waiting for work to do.</p><p>This is because nginx uses the hash of the client public ip address, so all users behind the same ip will be routed to the same backend, which isn't what we intend.</p><p>Nginx also has the ability to route the requests based on a cookie you define (on in case of servlet engines is caled JSESSIONID). But that feature is not available in the free nginx version, it's premium feature requiring a pricy subscription. <a href="https://docs.nginx.com/nginx/admin-guide/load-balancer/http-load-balancer/#enabling-session-persistence">https://docs.nginx.com/nginx/admin-guide/load-balancer/http-load-balancer/#enabling-session-persistence</a></p><p>So if you wan't to stay free of costs for the load balancer you have to choose something else.</p><p>There exist dedicated HA proxies for this, but we did choose to use the Apache webserver for this.</p><p>The basic confirguration for a apache reverse proxy is simple, a bit more complex with load balancing and even less documented for load balancing with websockets.</p><p>This is why this post exists, I did search (most of the?) internet for informations on how to achieve this, but only did find fragments of the solution and often with wrong parts in it.</p><p>So our solution does correctly proxy http/http2/websocket requests to the backend servers in a sticky way. The ssl/https configuration is not part of this post, but you can use standard ways for this.</p><p>This setup is valid for all Vaadin Flow 23.0 and 23.1 and 23.2. setups. <b>For Vaadin 23.3 and later, the push endpoints have been simplified for a better lb configuration.</b> <a href="https://github.com/vaadin/flow/issues/14641">https://github.com/vaadin/flow/issues/14641</a><br /></p><p>So here what our config looks like, we will explaing the severals parts later:</p><p># 1<br /></p><p><span style="font-family: courier;">ProxyRequests Off<br /></span></p><p><span style="font-family: courier;">#2<br />ProxyPass /images/ !<br />ProxyPass /.well-known/ !<br /></span></p><p><span style="font-family: courier;">#3 <br /></span></p><p><span style="font-family: courier;">RewriteEngine On<br />RewriteCond %{REQUEST_URI} ^/ [NC]<br />RewriteCond %{QUERY_STRING} transport=websocket [NC]<br />RewriteRule /(.*) balancer://backend-ws/$1 [P,L]<br /> </span></p><p><span style="font-family: courier;">#4<br />ProxyPass / balancer://backend/<br />ProxyPassReverse / balancer://backend/</span></p><p><span style="font-family: courier;">#5<br /></span></p><p><span style="font-family: courier;"><Proxy balancer://backend><br /> BalancerMember http://192.168.1.50:8080 route=backend1<br /> BalancerMember http://192.168.1.51:8080 route=backend2<br /> ProxySet stickysession=JSESSIONID<br /></Proxy><br /> </span></p><p><span style="font-family: courier;">#6<br /><Proxy balancer://backend-ws><br /> BalancerMember ws://192.168.1.50:8080 route=backend1<br /> BalancerMember ws://192.168.1.51:8080 route=backend2<br /> ProxySet stickysession=JSESSIONID<br /></Proxy></span><br /></p><p>And in your tomcat server.xml on the backend servers:</p><p><span style="font-family: courier;"><Engine name="Catalina" defaultHost="backend.service.ch" <b>jvmRoute="backend1"</b>></span></p><p><span style="font-family: courier;">...</span></p><p><span style="font-family: courier;"></Engine><br /></span><br />So lets explain the parts:</p><p>1. General proxy config<br /></p><p><span style="font-family: courier;">ProxyRequests Off</span></p><p><span style="font-family: courier;"><span style="font-family: arial;">Make sure to have this in your config, otherwise your webserver can be missused to proxy any request to the internet, turning your server in an open proxy.</span><br /></span></p><p><span style="font-family: courier;"></span></p><p><span style="font-family: courier;">#2<br />ProxyPass /images/ !<br />ProxyPass /.well-known/ !</span></p><p><span style="font-family: arial;">With these you can serve static content direcly from you apache webserver (As long as it has access to that content)</span></p><p><span style="font-family: courier;"><span style="font-family: arial;">The .well-known this is usually needed when you use letsencrypt certificates for https</span><br /></span></p><p><span style="font-family: courier;">#3 <br /></span></p><p><span style="font-family: courier;">RewriteEngine On<br />RewriteCond %{REQUEST_URI} ^/ [NC]<br />RewriteCond %{QUERY_STRING} transport=websocket [NC]<br />RewriteRule /(.*) balancer://backend-ws/$1 [P,L]<br /></span></p><p><span style="font-family: arial;">The roles above make sure to correctly handle http->websocket upgrade requests and send them to the websocket balancer.</span></p><p><span style="font-family: arial;">Depending on you application/backend you will need to tune the rewrites, but these here work for a vaadin application.</span></p><p><span style="font-family: arial;">It is known that a rewrite rule is not optimal from a performance point of view, but so far I know of no other solution, until Vaadin 24 will hopefully use a dedicated push/websocket endpoint.<br /></span></p><p><span style="font-family: courier;">#4<br />ProxyPass / balancer://backend/<br />ProxyPassReverse / balancer://backend/</span></p><p><span style="font-family: courier;"><span style="font-family: arial;">Here we route the normal http and http2 requests to the http balancer. Please take care to include the trailing / after the backend, otherwise you will receive strange errors like<span style="font-family: courier;"> "No protocol handler was valid for the URL /home (scheme 'balancer')</span></span>"<span style="font-family: arial;"> in your server error log</span><br /></span></p><p><span style="font-family: courier;">#5<br /></span></p><p><span style="font-family: courier;"><Proxy balancer://backend><br /> BalancerMember http://192.168.1.50:8080 route=backend1<br /> BalancerMember http://192.168.1.51:8080 route=backend2<br /> ProxySet stickysession=JSESSIONID<br /></Proxy><span style="font-family: arial;"><br />This is the load balancer to route the requests to the two backend servers, you can add more if you have more of them.</span></span></p><p><span style="font-family: courier;"><span style="font-family: arial;">The stickysession indicates to use the JSESSIONID cookie to match the requests to the correct backend. The name of the route should match your jvmRoute entry in the server.xml file for each backend.</span><br /></span></p><p><span style="font-family: courier;">#6<br /><Proxy balancer://backend-ws><br /> BalancerMember ws://192.168.1.50:8080 route=backend1<br /> BalancerMember ws://192.168.1.51:8080 route=backend2<br /> ProxySet stickysession=JSESSIONID<br /></Proxy></span></p><p><span style="font-family: arial;">Same as #5, but for the websocket requests.</span></p><p><span style="font-family: courier;"><span style="font-family: arial;">As you see in the balancer definitions, the backend servers are connected via unencrypted http/ws. If you need to use https/wss toward the backend servers too, then you can just replace the backend server definitions with https/wss. But of course you will then also have to handle the certificates on tomcat side too.</span></span></p><p><b><span style="font-family: courier;"><span style="font-family: arial;">Required apache modules for this to work:</span></span></b></p><p><span style="font-family: courier;"><span style="font-family: arial;">Apache should use the event mpm if possible, for better handling of http2 and websokets. Other mpm might work, I have not tested them.</span></span></p><p><span style="font-family: arial;">As for the modules themself, enable these:</span></p><p><span style="font-family: courier;">http2 -> For http/2 of course</span></p><p><span style="font-family: courier;">proxy -> General basic proxy funcionality</span></p><p><span style="font-family: courier;">proxy_balancer -> To used balancers toward the backend</span></p><p><span style="font-family: courier;">proxy_http -> For http 1.x proxy requests</span></p><p><span style="font-family: courier;">proxy_http2 -> For http/2 proxy requests</span></p><p><span style="font-family: courier;">proxy_wstunnel -> For websocket proxy stuff</span></p><p><span style="font-family: courier;">rewrite -> To identify and redirect websocket requests to the ws balancer</span></p><p><span style="font-family: courier;">lbmethod_byrequests -> type of loadbalancing to use <br /></span></p><p><span style="font-family: arial;">In debian you can just use a2enmod <module_name> to enable them, on other distributions when commands vary, but finally these modules must be active to have a full http/http2/ws load balancer for Vaadin.</span></p><p><span style="font-family: arial;">This setup work for Vaadin 23.1.x, for Vaadin 24 there is a discussion going on about having dedicated endpoint for push/websockets. <a href="https://github.com/vaadin/flow/issues/14641#issuecomment-1266519119">https://github.com/vaadin/flow/issues/14641#issuecomment-1266519119</a><br /></span></p><p><span style="font-family: arial;">And a documentation (still to be done) about Vaadin and reverse proxy setups<br /></span></p><p><span style="font-family: arial;"><a href="https://github.com/vaadin/docs/issues/1776#issuecomment-1272384234">https://github.com/vaadin/docs/issues/1776#issuecomment-1272384234</a><br /></span></p><p><span style="font-family: courier;"><br /></span></p><p></p>ZorkNikahttp://www.blogger.com/profile/00220798333873847668noreply@blogger.com0tag:blogger.com,1999:blog-5536625962775064923.post-32300932805494660282022-05-18T15:42:00.008+02:002023-02-02T18:13:29.469+01:00Cleanup huge WindowsApps folder<p>There is an <a href="http://techtuxwords.blogspot.com/2023/02/huge-windowsapps-folder-in-2023.html">updated post here</a>, with less details, but including the script.<br /></p><p>In some cases the "c:\Program Files\WindowsApps" folder starts to fill the harddisk.</p><p>We had one customer with a 256GB ssd, where the WindowsApps folder did take 180GB.</p><p>So what's going on, and how to cleanup this?</p><p>It's not clear why there are so many orphaned versions/installations in the WindowsApps folder, must be some bug somewhere in Windows 10 to cause this.</p><p>So, the first question is not realy answered, so what about the cleanup?</p><p>You can google for this and find a lot of results, but not many with a real solution.</p><p>The best post I did find is this one: https://www.tenforums.com/performance-maintenance/185009-how-clean-up-windowsapps-folder-3.html with a script to detect all orphanes on page 3 of the answers/discussions.</p><p>It works like a charm, the only thing missing is actually deleting the folder/files from the standard system, and not the recovery console.</p><p>The reason you need the recovery console, is the NFTS owner and rights of that special folder.</p><p>But of course there is a way arround this too:</p><p>1. Take ownership of the folder (and it's content) with takeown</p><p>2. Set the acl's to allow the current user to delete the folder+content with icacls</p><p>3. Finally, with 182 orphan folder, you don't want to accept each deletion manually, so we add the /Q argument to the RD command.</p><p>A small note, the takeown command uses either /d y on english systems for the confirmation or on german systems the /d j argument. So modify that line to match your confirmation letter</p><p>The lines from line number 120 onwards looks then like this<br /></p><p><span style="font-family: courier;">echo rem folder "%%z" (about !oldlineSize! Bytes^, about !SizeMB! MBytes^)<br /><b>echo takeown /F "%WA%\%%z" /r /d y<br />echo icacls "%WA%\%%z" /t /grant %USERNAME%:F</b><br />echo RD <b>/Q</b> /S "%WA%\%%z"</span><br /></p><p>So you can now run the script as admin, rename the resulting file into delorpahns.cmd and run that one as admin too and your WindowsAppps folder is clean once more.</p><p> </p><p>To have the complete script available in one place, here my enhanced version:</p><p> </p><p><span style="font-family: courier;">::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::<br />:: By Einstein1969 for www.tenforum.com <br />::<br />%= CleanWA =% @set "Version=0.1.4 BETA"<br />::<br />:: Detect orphaned dirs in %ProgramFiles%\WindowsApps, check for integrity/consistency<br />::<br />:: Requirements: Save to UTF-8. Use Lucida Console Font in CMD window. Run with double click over icon script.<br />:: Windows 10 version 1511 (build number 10586) onward<br />::<br />:: history:<br />:: 04/02/2022 0.1.4 BETA fix some minor bug and aesthetic improvements <br />:: /10/2021 0.1.4 BETA fix bug for elevated char ;,=() &^<br />:: 29/09/2021 0.1.3 BETA Search for applications that do not have InstallLocation set.<br />:: Enable support for Unicode UTF-8 and VT-ANSI<br />:: 25/09/2021 0.1.2 BETA removed debug, added run as administrator , thanks Matthew Wai<br />:: 25/09/2021 0.1.1 BETA add debug instruction for "file not found" bug/error.<br />::<br />:: ref: https://www.tenforums.com/tutorials/4689-uninstall-apps-windows-10-a.html<br />:: ref: https://docs.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences<br />::<br />::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::<br />@echo off & setlocal EnableDelayedExpansion&color 1f&title CleanWA %Version%<br /><br />Rem Choice the WindowsApps (WA) directory to check.<br />set "WA=%ProgramW6432%\WindowsApps"<br /><br /><br />Rem Check for Run as administrator.<br />call :Restart_as_Administrator %1<br /><br />Call :video_setting<br /><br />Rem check for permission on WA<br />if not exist "%WA%\." echo( & echo Error: Problem accessing "%WA%" & goto :the_end<br /><br />echo(<br />echo • Analyze "%WA%"<br />echo(<br /><br />Echo • Check for applications that do not have "InstallLocation" set.<br />echo(<br /><br />rem create list of registered app<br />> "%tmp%\CleanWA.RegisteredApps.tmp.txt" ^<br /> (<br /> rem exclude "system" applications in c:\windows folder<br /> powershell -Command "Get-AppxPackage -AllUsers | ? { $_.SignatureKind -ne 'System' } | sort -property {$_.InstallLocation+' '} | ForEach-Object {'{0,-40} {1,-20} {2}' -f $_.name,$_.version,$_.InstallLocation}"<br /> )<br /><br />type nul: > "%tmp%\CleanWA.RegisteredApps_good.tmp.txt"<br />type nul: > "%tmp%\CleanWA.RegisteredApps_NO_good.tmp.txt"<br />FOR /f "usebackq tokens=1,2,*" %%a in ("%tmp%\CleanWA.RegisteredApps.tmp.txt") do (<br /> if "%%c" equ "" ( <br /> echo( %CSI%7m? Warning: Registered app "%%a" does not have a "InstallLocation" set/defined. ?%CSI%27m<br /> echo(<br /> echo Rem Warning: Registered app "%%a" does not have a "InstallLocation" set/defined. >> "%tmp%\CleanWA.RegisteredApps_NO_good.tmp.txt"<br /> ) else echo(%%a %%b %%c >> "%tmp%\CleanWA.RegisteredApps_good.tmp.txt"<br />)<br /><br />echo v check finished.<br />echo(<br /><br />echo • Detect orphaned dirs<br />echo(<br /><br />type nul > "%tmp%\CleanWA.report_orphans.tmp.txt"<br />set "dn=0" & rem number of folders/directories<br />set /A "Size=0, Totsize=0,dirsO" <br />FOR /f "tokens=*" %%z IN ('dir /b /o:n "%WA%"') DO (<br /> set /a "dn+=1"<br /> <br /> FOR /f "tokens=1-4" %%g in ('dir /S /W /-C "%WA%\%%z"') do (set "oldlineSize=!line!" & set line=%%i)<br /> call :pad dn 4<br /> set /A "size=!oldlineSize:~0,-4!+0, sizeMB=size/105"<br /> echo • !dn! - Searching for folder:<br /> echo "%%z" (about !SizeMB! MBytes^) %CSI%0K<br /><br /> set "found="<br /> for /f "usebackq tokens=1,2,*" %%a in ("%tmp%\CleanWA.RegisteredApps_good.tmp.txt") do if not defined found (<br /> rem echo • Pkg. InstallLocation "%%c" %CSI%0K %RI%<br /> set _V_=%%z<br /> set v1="x!_V_:%%a_%%b=!x"<br /> set v2="x!_V_!x"<br /> if !v1! NEQ !v2! (<br /> set Found=1<br /> rem echo( %CSI%102m? Found an app that use this folder ?%CSI%44m : %CSI%102m"%%a"%CSI%44m version: "%%b" %CSI%0K<br /> )<br /> )<br /><br /> if defined found (<br /> echo(%RI%%RI%%RI%<br /> ) else (<br /> rem check for unknown folder/dir <br /> rem known:_x64_, _x86_, _neutral_ .... others?<br /> set v1="x!_V_:_x64_=!x"<br /> set v2="x!_V_!x"<br /> set "OK=N"<br /> if !v1! NEQ !v2! set "OK=Y"<br /> set v1="x!_V_:_x86_=!x"<br /> if !v1! NEQ !v2! set "OK=Y"<br /> set v1="x!_V_:_neutral_=!x"<br /> if !v1! NEQ !v2! set "OK=Y"<br /><br /> if !OK! NEQ Y (<br /> echo(<br /> echo %CSI%43m? No Match folder: "%%z" ?%CSI%44m%CSI%0K<br /> echo(<br /> echo(<br /> ping -n 2 127.0.0.1 >nul<br /> ) else (<br /> echo(<br /> echo %CSI%101m? orphans folder! ?%CSI%44m%CSI%0K<br /> echo(<br /> echo(<br /> rem why 105? 1024*1024/10000 ~ 105<br /> set /A "Totsize+=size, TotsizeMB=Totsize/105, dirsOrphans+=1"<br /> title CleanWA %Version% [Tot. space orphans: about !TotsizeMB! MB] [dirs/folder orphans: !dirsOrphans!]<br /> ( <br /> echo rem folder "%%z" (about !oldlineSize! Bytes^, about !SizeMB! MBytes^)<br /> echo takeown /F "%WA%\%%z" /r /d y<br /> echo icacls "%WA%\%%z" /t /grant %USERNAME%:F<br /> echo RD /Q /S "%WA%\%%z"<br /> echo( <br /> ) >> "%tmp%\CleanWA.report_orphans.tmp.txt"<br /> )<br /> )<br /> rem pathping 127.0.0.1 -n -q 1 -p 100 >nul<br />)<br />echo(<br />echo(<br />echo(<br />echo v check finished.<br />echo(<br />echo dirs/folder orphans: !dirsOrphans!<br />echo(<br />echo Tot. space orphans: about !TotsizeMB! MB<br />echo(<br /><br />>nul: copy /a "%tmp%\CleanWA.RegisteredApps_NO_good.tmp.txt" + /a "%tmp%\CleanWA.report_orphans.tmp.txt" "%tmp%\CleanWA.report.tmp.txt"<br /><br />echo coping Report/script "%tmp%\CleanWA.report.tmp.txt" for offline delete in \Users\Public<br />copy "%tmp%\CleanWA.report.tmp.txt" \Users\Public<br />echo(<br />pause<br /><br />start notepad "\Users\Public\CleanWA.report.tmp.txt"<br /><br />:the_end<br />:: pause if double clicked on instead of run from command line.<br />echo %cmdcmdline% | findstr /I /L %comspec% >nul 2>&1<br />if %errorlevel% == 0 echo( & pause<br />exit /B 0<br />goto :eof<br />::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::<br />:::::::::::::::::::::::::::::::::: SUBROUTINE ::::::::::::::::::::::::::::::<br />::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::<br />:Restart_as_Administrator<br />(Fsutil Dirty Query %SystemDrive%>Nul)&&(<br /> if "%1" neq "admin" (<br /> start /MAX %~f0 admin<br /> Exit<br /> )<br />)||( <br /> mode con cols=90 lines=20<br /> echo( & echo It is necessary to start the script with administrative rights.<br /> echo( & echo Please wait ... I am restarting the script with administrative rights. <br /> echo( & echo Answer "YES" to the next User Account Control UAC request to continue <br /> echo( running this script with administrative permissions. & echo(<br /> timeout /t 4<br /> powershell.exe -c "Start -WindowStyle Maximized -Verb RunAs cmd /c, ("^""%~f0"^"" -replace '[;,=() &^]', '^$0'), "admin" " & Exit<br />)<br />goto :eof<br />::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::<br />:video_setting<br /> For /F %%a In ('echo prompt $E^| cmd') Do Set "ESC=%%a" <br /> set "CSI=%ESC%[" & set "RI=%ESC%M"<br /> set "echoVT=<nul set/p.="<br /> rem get windows size<br /> for /f "tokens=1,2 skip=3" %%A in ('powershell -command "$Host.ui.rawui.WindowSize"'<br /> ) do set /a windowWidth=%%A, windowHeight=%%B, sm_e=%%B - 3<br /> mode con: COLS=%windowWidth% LINES=%windowHeight%<br /> Rem Setting Scrolling Margins<br /> echo %CSI%4;%sm_e%r<br /> rem set UTF-8<br /> chcp 65001<br /> cls<br />goto :eof<br />::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::<br />:pad<br /> set "pad=!%1!"<br /> for /L %%L in (1,1,%2) do set "pad= !pad!"<br /> set "pad=!pad:~-%2!"<br /> set "%1=!pad!"<br />goto :eof<br />::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::</span><br /></p><p><br /></p><p><br /></p>ZorkNikahttp://www.blogger.com/profile/00220798333873847668noreply@blogger.com1tag:blogger.com,1999:blog-5536625962775064923.post-81203034039293051802022-04-21T10:10:00.007+02:002022-04-21T10:10:36.777+02:00MS SQL Server can't register SPN when started with a service account<p>When you change the service account used by the MS SQL server services, they often are not abel to register the corresponding SPN in active directory.</p><p>You should see these messages in the SQL server log when it's working correctly</p><p><span style="font-family: courier;">The SQL Server Network Interface library successfully registered the
Service Principal Name (SPN) [ MSSQLSvc/SQL.testdomain.in:24629 ] for
the SQL Server service.
</span></p><p></p><p><img alt="SQL Server error log for default instance" src="https://www.sqlshack.com/wp-content/uploads/2019/07/sql-server-error-log-for-default-instance.png" style="display: block; margin: 0px auto;" /> <br /></p><p>In the case you get errors like this, the SPN registration (and therefore later on the lookup via AD) is not working<br /></p><p><span style="font-family: courier;">The SQL Network Interface library could not register the Service
Principal Name (SPN) for the SQL Server service. Error: 0x54b. Failure
to register an SPN may cause integrated authentication to fall back to
NTLM instead of Kerberos. This is an informational message. Further
action is only required if Kerberos authentication is required by
authentication policies. </span></p><p> For a service account to be able to register the SPN you need to set these rights on the AD user account:</p><p><img alt="" src="data:image/png;base64,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" /></p><p>Now you just have to restart the MS SQL service, and it should be able to register the SPN in AD.</p><p>If you still receive the error message, then it's because the corresponding SPN's are still/already registered on another object (mostly the computer account of the MS SQL server) and the service account has no rights to modify them (Since we did only allow it to modify it's own rights)</p><p>So the simplest way to do this is to use the setspn command to remove the stale entries.</p><p>You can look what SPN entries are registered for a specific AD object with this command:</p><p><span style="font-family: courier;">setspn -l domain\sql-server</span></p><p>You will then probably see something like this:</p><ul><li>
MSSQLSvc/ sql-server.domain.local
</li><li>
MSSQLSvc/ sql-server.domain.local:1433 </li></ul><p>So you can also remove them from the object with:</p><p><span style="font-family: courier;">setspn -d MSSQLSvc/sql-server.domain.local domain\sql-server</span></p><p><span style="font-family: courier;">setspn -d MSSQLSvc/sql-server.domain.local:1433 domain\sql-server</span></p><p></p><p>Now you restart the MS SQL service and it should be able to register.</p><p>If it still throws errors, then the SPN is probably assigned to another account. In that case just try to add the spn manually, and it will tell you where the duplicate SPN can be found.</p><p><span style="font-family: courier;">setspn -a MSSQLSvc/sql-server.domain.local domain\service-account</span></p><p>This can also happen when you switch from one service account to another.<br /></p><p><br /></p><p><br /></p>ZorkNikahttp://www.blogger.com/profile/00220798333873847668noreply@blogger.com0tag:blogger.com,1999:blog-5536625962775064923.post-62170347667315849272022-02-28T17:32:00.005+01:002022-02-28T17:33:09.191+01:00Outlook does not allow you to subscribe to all calendars of distribution lists<p> In previous Outlook versions you could subsribe to all calendars of all members of a distribution group, by just selecting it in the address book.</p><p></p><p>With current Outlook versions this mostly don't work and you receive the message that you have to subscribe to the calendars one by one.</p><p>In german this is the error message you get: </p><p><img src="https://support.aarboard.ch/api/v1/ticket_attachment/8021/15225/25344?view=inline" style="max-width: 100%; width: 817px;" /></p><p>The same behaviours also occurs, when you try to subscribe to all rooms at the same time.</p><p>To get this working again, you have to <b>disable</b> the "Shared calendar improvements", at least for the duration when subscribing to the calendars.</p><p>When this checkbox is disabled, you can again subscribe multiple calendars in one step.</p><p><img alt="You can turn on the shared calendar improvements with a checkbox." class="x-hidden-focus" src="https://support.content.office.net/en-us/media/a087b508-ac30-4c4a-bae1-45e2842eb9e5.png" /> <br /></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p><a href="https://support.microsoft.com/en-us/office/outlook-calendar-sharing-updates-c3aec5d3-55ce-4cea-84b0-80aab6d8dc26">https://support.microsoft.com/en-us/office/outlook-calendar-sharing-updates-c3aec5d3-55ce-4cea-84b0-80aab6d8dc26</a></p><p>Please be aware, that you should reenable this setting after subscription, otherwise your subscribed calendard will get lost when you have no connection to the server, or working offline.</p><p><br /></p><p> And a small side note: The GPO policy mentioned in the linked article no longer exists, so don't look for it in current admx templates.</p><p>Also setting the mentioned policy registry key seems to have no effect with current outlook versions as of 2022.<br /></p><p>There is a new setting for REST communication with calendar server, but this seems to not solve the subscribe problem.<br /></p>ZorkNikahttp://www.blogger.com/profile/00220798333873847668noreply@blogger.com0tag:blogger.com,1999:blog-5536625962775064923.post-50942139037682248262021-10-15T11:19:00.005+02:002022-02-21T09:29:14.392+01:00Reactivate Zabbix agent in TrueNAS after update<p>When you have installed the Zabbix agent as mentioned in my <a href="http://techtuxwords.blogspot.com/2020/10/install-zabbix-agent-on-truenas.html">previous post</a>, then you will notice that Zabbix gets deactivated wqhen you install TrueNAS updates.</p><p>To get the agent running again, you only need to reactivate it in rc.conf</p><ol><li>Enable daemon<br />
<code>echo 'zabbix_agentd_enable="YES"' >> /etc/rc.conf <br /></code></li><li>Start daemon:
<div class="language-bash highlighter-rouge">
<div class="highlight">
<code>/etc/rc.d/zabbix_agentd start
</code>
</div>
</div>
</li><li>Make config files persistent and survive reboots:
<div class="language-bash highlighter-rouge">
<code>cp /etc/rc.conf /conf/base/etc/ </code></div><div class="language-bash highlighter-rouge"><code>cp /etc/rc.d/zabbix_agentd /conf/base/etc/rc.d/<br />
mkdir /conf/base/etc/zabbix_agentd<br />
cp /etc/zabbix_agentd.* /conf/base/etc/</code>
</div>
</li>
</ol>
<p>Of course it's a good moment to install the latest zabbix agent too.</p><p>For this take the<a href="https://www.zabbix.com/de/download_agents?version=5.0+LTS&release=5.0.16&os=FreeBSD&os_version=11.2&hardware=amd64&encryption=GnuTLS&packaging=Archive&show_legacy=0" target="_blank"> latest version</a> matching your server version and copy the /bin and /sbin to /usr/local and restart the agent.</p><p>If someone has an idea, on how to make the "Enable daemon" step survive a minor TrueNAS upgrade, I would be glad for some hints ;)<br /></p>
ZorkNikahttp://www.blogger.com/profile/00220798333873847668noreply@blogger.com0tag:blogger.com,1999:blog-5536625962775064923.post-22565086643555863692021-10-11T12:01:00.003+02:002021-10-11T12:01:56.002+02:00ERROR: (gcloud.iam.service-accounts.keys.create) FAILED_PRECONDITION: Precondition check failed.<p>When you try to create a key for a service account in google cloud via the <span style="font-family: courier;">gcloud iam service-accounts keys create</span> command, it can occur that you receive this error <span style="font-family: courier;">ERROR: (gcloud.iam.service-accounts.keys.create) FAILED_PRECONDITION: Precondition check failed.</span></p><p><span style="font-family: inherit;">Unfortunally searching for this error does not show up much, and adding <span style="font-family: courier;">--verbosity=debug</span> does not turn up more information.</span></p><p><span style="font-family: inherit;">The reason for this error is, that a single service account can have a maximum of (currently) 10 active keys.</span></p><p><span style="font-family: inherit;">If you try to create one more, then you will receive the above error message.</span></p><p><span style="font-family: inherit;">The only way to work arround the problem is to remove older keys, which are (hopefully) no longer used.</span></p><p><span style="font-family: inherit;">You can do this either via the gui or the </span><span style="font-family: inherit;"><span class="normalfont"><code dir="ltr">gcloud iam service-accounts keys delete</code> command</span></span></p><p><span style="font-family: inherit;"><span class="normalfont"><code dir="ltr"><span style="font-family: inherit;"><span style="font-family: inherit;"> </span></span></code></span></span></p><p><span style="font-family: inherit;"><span class="normalfont"><span style="font-family: inherit;">Found the solution thanks to <a href="https://gist.github.com/maelvls/c23558b717422c4c648f4258a7f2fb1">https://gist.github.com/maelvls/c23558b717422c4c648f4258a7f2fb1</a> since in the google documentation there is no reference to a limit on the number of keys per service account</span></span> </span></p>ZorkNikahttp://www.blogger.com/profile/00220798333873847668noreply@blogger.com0tag:blogger.com,1999:blog-5536625962775064923.post-88956393679194734802020-10-21T15:20:00.001+02:002020-10-21T15:20:06.546+02:00Install Zabbix agent on TrueNAS<p> In my <a href="http://techtuxwords.blogspot.com/2018/07/install-zabbix-agent-on-freenas-11x.html" target="_blank">previous article</a> from 2018 I did mention how to install teh Zabbix agent on FreeNAS.</p><p>Since then two years are passed and FreeNAS has been replaced by <a href="https://www.truenas.com/" target="_blank">TrueNAS</a> provides the same functionality in a new version with a new name.</p><p>The steps for installation are remained the same, but you won't need to build the agent package yourself, you can use the packages provided from Zabbix for FreeBSD.</p><p>So lets see what you have to do now:</p><p>1. Download the binary package from the Zabbix webpage at <a href="https://www.zabbix.com/de/download_agents?version=4.0+LTS&release=4.0.25&os=FreeBSD&os_version=11.2&hardware=amd64&encryption=GnuTLS&packaging=Archive">https://www.zabbix.com/de/download_agents?version=4.0+LTS&release=4.0.25&os=FreeBSD&os_version=11.2&hardware=amd64&encryption=GnuTLS&packaging=Archive</a></p><p>It's no problem that FreeBSD 12.x is not listed, the 11.2 packages still work</p><p>2. Unpack the /bin and /sbin folders into /usr/local of your TrueNAS server</p><p>3. Unpack the /conf/* into /etc<br /></p><p>4. Create a use and group zabbix so your agent wont run as root, you need to do this via GUI, otherwiese the account will be gone after reboot</p><p>5. Edit your /etc/zabbit_agentd:conf to match your needs</p><p>6. Enable daemon<br />
</p><div class="language-bash highlighter-rouge">
<div class="highlight"><code>echo 'zabbix_agentd_enable="YES"' >> /etc/rc.conf
</code> </div><div class="highlight"> </div><div class="highlight">Create <code class="highlighter-rouge">/etc/rc.d/zabbix_agentd</code>:
<div class="highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code>#!/bin/sh
# PROVIDE: zabbix_agentd
# REQUIRE: DAEMON
# KEYWORD: shutdown
#
# Add the following lines to /etc/rc.conf.local or /etc/rc.conf to
# enable zabbix_agentd:
#
# zabbix_agentd_enable (bool): Set to NO by default. Set it to YES to
# enable zabbix_agentd.
#
. /etc/rc.subr
name="zabbix_agentd"
rcvar=zabbix_agentd_enable
start_precmd="zabbix_precmd"
required_files="/etc/zabbix_agentd.conf"
# read configuration and set defaultsc
load_rc_config "$name"
: ${zabbix_agentd_enable="NO"}
#: ${zabbix_agentd_pre:=/etc/${name}.pre.sh}
zabbix_agentd_conf="/etc/zabbix_agentd.conf"
if [ ! -z "$zabbix_agentd_conf" ] ; then
zabbix_agentd_flags="${zabbix_agentd_flags} -c ${zabbix_agentd_conf}"
required_files=${zabbix_agentd_conf}
fi
zabbix_precmd()
{
if [ ! -z "$zabbix_agentd_pre" ] ; then
if [ -e $zabbix_agentd_pre ] ; then
. $zabbix_agentd_pre
fi
fi
}
command="/usr/local/sbin/${name}"
run_rc_command "$1" run_rc_command "$1"
</code></pre>
</div>
</div> Make executable:
<ol><li><div class="language-bash highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code>chmod +x /etc/rc.d/zabbix_agentd
</code></pre>
</div>
</div>
</li><li>Start daemon:
<div class="language-bash highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code>/etc/rc.d/zabbix_agentd start
</code></pre>
</div>
</div>
</li><li>Make config files persistent and survive reboots:
<div class="language-bash highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code>cp /etc/rc.conf /conf/base/etc/
cp /etc/rc.d/zabbix_agentd /conf/base/etc/rc.d/<br />mkdir /conf/etc/zabbix_agentd<br />cp /etc/zabbix_agentd.* /conf/base/etc/<code><br />cp /etc/zabbix_agentd.* /conf/base/etc/</code> </code></pre><pre class="highlight"><code> </code></pre><h3 id="daemon-configuration">Zabbix configuration</h3>
<code>Use the template from the zabbix wiki for the host monitoring</code>
<code><a href="http://zabbix.org/wiki/File:Template_OS_FreeNAS.xml">http://zabbix.org/wiki/File:Template_OS_FreeNAS.xml</a></code><pre class="highlight"><code> </code></pre></div></div></li></ol></div>
</div>ZorkNikahttp://www.blogger.com/profile/00220798333873847668noreply@blogger.com1tag:blogger.com,1999:blog-5536625962775064923.post-72202799045780763892020-09-01T11:22:00.003+02:002020-09-01T22:57:23.206+02:00Use perdition as ssl offload proxy for imap / pop and managesieve<p> In modern setups you often have an ingress controller, which does the ssl termination of the connections and then routes the traffic to the correct backend(s)</p><p>For kubernetes and http(s), often nginx is used for that task.</p><p>When you wish to do the same for imap and/or pop, then it also possible to use nginx for this.</p><p><a href="https://docs.nginx.com/nginx/admin-guide/mail-proxy/mail-proxy/">https://docs.nginx.com/nginx/admin-guide/mail-proxy/mail-proxy/</a></p><p>But the main drawback is, that you need to implement some authentication and routing based on an http request.Also the managesieve protocol isn't supported.<br /></p><p>If you don't wish to do the hassle with this, or you haven't the required infos to do it, then perdition can handle this be used as a full imap/pop/managesieve proxy.</p><p>The basic setup is quite simple, but has a few things to be aware of, when using it with ssl and/or ipv6.</p><p>When you enable ssl, then you have to specify the certificate files.</p><p>Usually something like this:</p><p>ssl_ca_file /etc/postfix/ssl/ssl-root.ca<br />ssl_cert_file /etc/postfix/ssl/myserver.crt<br />ssl_key_file /etc/postfix/ssl/myserver.key</p><p>When you then start perdition, it will probably log some warning about not beeing able to read the DH parameters from the certificate file.<span class="hl fld" id="l_723" style="padding-left: 1.5em;"><span class="hl str"> </span></span></p><p><span style="font-family: courier;"><span class="hl fld" id="l_723" style="padding-left: 1.5em;"><span class="hl str">could not read DH params from cert file</span></span></span></p><p>Modern OpenSSL configurations require Diffie-Hellman values to generate secure keys in the exchange.</p><p>If your certificate does not have these embedded in it, you can generate them yourself and add them to the certificate.</p><p></p><pre><code>openssl dhparam -out dhparams.pem 4096</code></pre><p></p><p>Then just append the content of the dhparams.pem file to your .crt file and perdition has the required DH values.</p><p>The second thing you might struggle with, when you start perdition on an IPv6 enable host, then perdition will only bind the IPv4 address and not to the IPv6 address.</p><p>Unfortunally the documentation is lacking in this area, as how to bind the IPv6 ports too.</p><p>The correct syntax is to use this in the perdition.imap4s etc. files:</p><p><span style="font-family: courier;">bind_address 88.xx.xx.xx,"[2a01:xxx:xxx:xxx::xxx]"</span></p><p></p><p>Please note that you must specify both IPvç and IPv6 addresses, and also that the IPv6 "[::]" will not work.</p><p>You have to specify the IPv6 address and enclose it in "[...]", including the " characters.</p><p>Configuring perdition as managesieve proxy is also not very well documented.</p><p>Specifying the sieve capabilities is rather tricky, here a wroking example:<br /></p><p><span style="font-family: courier;">capability \<br />"\"IMPLEMENTATION\" \"Cyrus timsieved\" "\<br />"\"SIEVE\" \"comparator-i;octet "\<br />"comparator-i;ascii-numeric "\<br />"fileinto "\<br />"reject "\<br />"vacation "\<br />"imapflags "\<br />"notify "\<br />"envelope "\<br />"relational "\<br />"regex "\<br />"subaddress "\<br />"copy\" "\<br />"\"SASL\" \"PLAIN\""</span><br /><br /> <br /></p><p>The important things to note in this:</p><p>Use \" to delimit the capabilities, and use <b>two</b> spaces to delimit the capability lines .</p><p>Have a look at the base config file perdition.conf as a staring point</p><p>If you have clients using K9 mail (And probably other too), then you might remove all "AUTH=..." settings from the imap capability string.</p><p><a href="https://lists.vergenet.net/pipermail/perdition-users/2011-August/002547.html">https://lists.vergenet.net/pipermail/perdition-users/2011-August/002547.html</a><br /></p><p>Please also see my upcomming post on monitoring perdition with Zabbix<br /></p><p><br /></p>ZorkNikahttp://www.blogger.com/profile/00220798333873847668noreply@blogger.com0tag:blogger.com,1999:blog-5536625962775064923.post-55483291807000199392020-08-25T15:01:00.002+02:002020-08-25T15:01:36.603+02:00Automatically remove write protection from USB Disks in Backup Exec<p>Veritas BackupExec has a default, which flags disks which have been offline for more than 32 days as write protected.</p><p>BackupExec has expiration dates for each backup you have done. Once this date is reached, BackupExec does free up the disk space and deletes the old backups.<br /></p><p>The idea behind this is, that these are disks which contain older backups, which should not automatically be purged from disk.Otherwise, when you connect the disk with the monthly backup of january on the server in june, for some restore, then BackupExec would remove these old backup sets.</p><p>That's usually not what you wish to have, this is why in the default this 32 day rule exists.</p><p>Of course you can tell BackupExec to either not set this write protection at all, or only for some longer time period. There is also a dangerous option, to allow BackupExec to delete all expired backup sets.</p><p>The default is usually fine, until you reinsert your january 2019 disk in january 2020. Then the disk will be write protected and you will have to remove the write protection first, or your backup jobs will fail.</p><p>Since this is a manual action you have to do on a regular basis, you can also automate it with some scripts.</p><p>With powershell und the windows task scheduler you can remove the write protection of the connected drives.</p><p>One important thing to note is, you must schedule the powershell script via task scheduler, if you define it as an "Run before job" in BackupExec, then the job will not start since it sees no writable disk in then system, and also does not start the "pre job run script"</p><p>This is the powershell script, which remove the write protection on all online disks in BackupExec, store it in a location on C:\...., for example as <span style="font-family: courier;">"c:\Program Files\Veritas\Backup Exec\Scripts\TurnWriteProtectedOff.ps1" </span><br /></p><p></p><p><span style="font-family: courier;"><# This script does remove the virtaul write protection on any online disks<br /> This way USB disks which had not been online for a long time wil be overwritable again<br /> 2020 a.schild@aarboard.ch<br />#><br />Import-Module "c:\Program Files\Veritas\Backup Exec\Modules\BEMCLI\BEMCLI.Scripts.psm1"<br /><br />$disks= Get-BEStorageDevice<br />foreach ($d in $disks) {<br /> if ($d.Servers.IsOnline -eq "true") {<br /> # $d | Format-Table Name<br /> $d | Set-BEDiskStorageDevice -VirtualWriteProtectionEnabled $false<br /> }<br />}</span><br /><br /></p><p>In your task scheduler you then schedule it to be run 5-10 minutes before the regular backup job.</p><p>As command specify your powershell.exe as<span style="font-family: courier;"> "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe"</span></p><p>In the script argugemt you pass:</p><p><span style="font-family: courier;"> -File "C:\Program Files\Veritas\Backup Exec\Scripts\TurnWriteProtectedOff.ps1"</span><br /></p><p>And define it to be run always, with no network resources and with highest priority.<br /></p>ZorkNikahttp://www.blogger.com/profile/00220798333873847668noreply@blogger.com0tag:blogger.com,1999:blog-5536625962775064923.post-50869046073965680632019-09-26T15:55:00.002+02:002019-09-26T15:55:33.326+02:00Startup problems with php-fpm and ldap user backend on Debian<h2>
Startup problems with php-fpm and ldap user backend on Debian </h2>
Do you use php-fpm together with an ldap backend for user authentication, then you probably have seen this message in your boot logs:<br />
<br />
<span style="font-family: "Courier New", Courier, monospace;">[26-Sep-2019 14:58:34] ERROR: [pool XXXXXX] cannot get uid for user 'XXXXXXXX'</span><br />
<br />
When using the php5.6-fpm / php7.x-fpm versions of the PHP fpm process can cause startup problems, when the users are provided via the nslcd service.<br />
<br />
The reason is, that the ldap user backend is starting after the php fpm process(es)<br />
<br />
Fortunately this is easy to solve, just edit your /etc/init.d/php7.3-fpm init script and add the user backend service(s) to the Required-Start section <br />
<br />
It looks like this: <br />
<span style="font-family: "Courier New", Courier, monospace;"># Required-Start: $remote_fs $network</span><br />
<br />
<span style="font-family: inherit;">So to add nslcd (and recommended nscd too) results in this line</span><br />
<br />
<span style="font-family: "Courier New", Courier, monospace;"># Required-Start: $remote_fs $network nslcd nscd</span><br />
<br />
<br />
<span style="font-family: inherit;">To enable the new dependencies of your service starts, just disable the service and reenable it.</span><br />
<br />
<span style="font-family: "Courier New", Courier, monospace;">systemctl disable php7.3-fpm </span><br />
<span style="font-family: "Courier New", Courier, monospace;">systemctl enable php7.3-fpm</span><br />
<br />
<span style="font-family: inherit;">After this, you can reboot your server and the fpm processes should startup just fine</span><br />
<span style="font-family: "Courier New", Courier, monospace;"><span style="font-family: inherit;"> </span> </span>ZorkNikahttp://www.blogger.com/profile/00220798333873847668noreply@blogger.com0tag:blogger.com,1999:blog-5536625962775064923.post-66935278617708014962019-07-16T16:51:00.000+02:002019-07-16T16:51:19.575+02:00Chromium 75.0.3770.xx does submit html forms twiceWhen you have customers which use chromium on Ubuntu 18.04 LTS, then you might see duplicate form posts in your applications.<br />
<br />
This is a very nasty bug introduced somewhere between the 74.0.3729.169 and 75.0.3770.80 releases.<br />
Here a few references to the problem, which seems to be still "work in progress"<br />
<br />
<ul>
<li><a class="external-link" href="https://stackoverflow.com/questions/56488687/duplicate-requests-after-chrome-update-to-version-75-0-3770-80-official-build" rel="nofollow">https://stackoverflow.com/questions/56488687/duplicate-requests-after-chrome-update-to-version-75-0-3770-80-official-build</a><br />
</li>
<li><a class="external-link" href="https://bugs.chromium.org/p/chromium/issues/detail?id=977882" rel="nofollow">https://bugs.chromium.org/p/chromium/issues/detail?id=977882</a><br />
</li>
<li><a class="external-link" href="https://support.google.com/chrome/thread/8616084?hl=en" rel="nofollow">https://support.google.com/chrome/thread/8616084?hl=en</a></li>
</ul>
This does not help the customers, since we need a solution now, and not in a few days/weeks.<br />
<br />
On ubuntu the simplest is to roll back to the last working version 74.0.3729.169<br />
<br />
How to do this:<br />
<br />
Login in the console of your system(s) and do this:<br />
<br />
<span style="font-family: "Courier New", Courier, monospace;">cd /tmp </span><br />
<span style="font-family: "Courier New", Courier, monospace;">rm chromium-*<br /><br />wget -q http://launchpadlibrarian.net/424897539/chromium-browser_74.0.3729.169-0ubuntu0.18.04.1_amd64.deb<br />wget -q http://launchpadlibrarian.net/424897541/chromium-codecs-ffmpeg-extra_74.0.3729.169-0ubuntu0.18.04.1_amd64.deb<br />wget -q http://launchpadlibrarian.net/424897535/chromium-browser-l10n_74.0.3729.169-0ubuntu0.18.04.1_all.deb<br /><br /><br />dpkg -i chromium-*.deb</span><br />
<span style="font-family: "Courier New", Courier, monospace;"><span style="font-family: "Courier New", Courier, monospace;">rm chromium-*</span></span><br />
<span style="font-family: "Courier New", Courier, monospace;"><span style="font-family: "Courier New", Courier, monospace;"> </span><br />apt-mark hold chromium-browser<br />apt-mark hold chromium-browser-l10n<br />apt-mark hold chromium-codecs-ffmpeg-extra</span><br />
<br />
<br />
This installs the 74er version and prevents future upgrades to install bad versions.<br />
Of course once a working 75 or 76 release is available, you have to unhold the packages<br />
<br />ZorkNikahttp://www.blogger.com/profile/00220798333873847668noreply@blogger.com0tag:blogger.com,1999:blog-5536625962775064923.post-23859701628548871592019-03-28T18:01:00.002+01:002019-03-29T17:34:50.532+01:00Generate one page PDF calendars with entriesGenerating a on epage pdf calendar isn't that difficult.<br />
Just draw the month grid and put the entries into the corresponding matrix at the correct places.<br />
<br />
But wait, is it that easy?<br />
<br />
- What do you do when the number of entries in one grid cell use more space than is available?<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEik7G9Dg_dio4_Bbym-z9b7Qtxe6V7L3EXAd2IC-upEHH-UGsgMF5hg_uACKdpm7Y3BLDGkV_D5eOQ7a1TxRiAYU2RcmmUQtLnWo5oHvgmZkyEJ5fgZwYXH2sp93LjISQPCSuUKQCUHc0c/s1600/calendar-overflow.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="912" data-original-width="1293" height="225" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEik7G9Dg_dio4_Bbym-z9b7Qtxe6V7L3EXAd2IC-upEHH-UGsgMF5hg_uACKdpm7Y3BLDGkV_D5eOQ7a1TxRiAYU2RcmmUQtLnWo5oHvgmZkyEJ5fgZwYXH2sp93LjISQPCSuUKQCUHc0c/s320/calendar-overflow.png" width="320" /></a></div>
<br />
<br />
To solve this problem in php, I did just write a class which handles this problem.<br />
The <a href="https://github.com/a-schild/pdfcalendarbuilder" target="_blank">PdfCalendarBuilder library</a> hosted on github solves this problem in two ways:<br />
<br />
- First it trys to resize the row heights, to distribute the free height across the rows, so everything still fits on one page<br />
- The secon option, if the content is still too large, is to reduce the font size of the entries until everything has place on the same page<br />
<br />
Both features can be de/activated independently of each other, but best results are done when both remain activated.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEix_XygVMssf-hLmGAx5TWXDjuc4em4n2GRmvUAeWuVEC1fpoHUwfAALs_AtUBMPWmElAQgOgw9C877tRMIt-hdhPgpkpbr1szdj7_Y_DLRVvrtiC5i9Z-emS_7G2jTcN1sq7i8e-urshM/s1600/calendar-resize-row2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="908" data-original-width="1290" height="225" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEix_XygVMssf-hLmGAx5TWXDjuc4em4n2GRmvUAeWuVEC1fpoHUwfAALs_AtUBMPWmElAQgOgw9C877tRMIt-hdhPgpkpbr1szdj7_Y_DLRVvrtiC5i9Z-emS_7G2jTcN1sq7i8e-urshM/s320/calendar-resize-row2.png" width="320" /></a></div>
<br />
<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgB4_drg3HQdaDKtPgGODlH19eTPMOug6KQd-Y2TFRaoxnQ2KYQS7mQfz2fVVxL9ZvKHdAdftzZz3vQl-CV8Lewdol1F1tF7A8karN99ShTtjPYj9H_rH8HViw-1HcWzQfAddVPvslTLyo/s1600/calendar-resize-rows-shrink-fontsize.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="910" data-original-width="1291" height="225" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgB4_drg3HQdaDKtPgGODlH19eTPMOug6KQd-Y2TFRaoxnQ2KYQS7mQfz2fVVxL9ZvKHdAdftzZz3vQl-CV8Lewdol1F1tF7A8karN99ShTtjPYj9H_rH8HViw-1HcWzQfAddVPvslTLyo/s320/calendar-resize-rows-shrink-fontsize.png" width="320" /></a></div>
<br />
<br />
<br />
There are still a few things to work out in the library, such as handling entries which span days or things like full-day events which should be rendered differently.<br />
<br />
But the basic stuff already works fine, even with event categories and legends.<br />
It also does not matter what paper siez you choose, just modify the font sizes as you need them, the defaults are good for A4 paper.<br />
<br />
And to help you integrate it in your own projects, the whoche whole library is licensed under the Apache 2.0 license.<br />
But please send back enhancements, error reports or other ideas to the project page.ZorkNikahttp://www.blogger.com/profile/00220798333873847668noreply@blogger.com0tag:blogger.com,1999:blog-5536625962775064923.post-63660380589068994712019-01-22T09:13:00.000+01:002019-01-22T09:13:07.302+01:00Monitor letsencrypt certificates with Zabbix<h2>
Monitor letsenrcypt certificates with Zabbix</h2>
<a href="https://letsencrypt.org/" target="_blank">Letsenrcypt</a> is a great free system to automatically provide ssl/tls certificates for your website(s)<br />
<a href="https://www.zabbix.com/" target="_blank">Zabbix </a>is a great free system to monitor your IT infrastructure<br />
<br />
One of the main features of Zabbix is the ability to extend it with any kind of monitoring scripts.<br />
So when you do use letsencrypt certificates, you can also monitor them from Zabbix.<br />
<br />
There exists a template you can add to the Zabbix server, and the required config and script files you place on the agents.<br />
<br />
These can be found <a href="https://github.com/a-schild/zabbix_letsencrypt" target="_blank">here</a>.<br />
<br />
It provides these features:<br />
- Autodiscovery of all active letsencrypt certificates<br />
- Monitor the lifetime of the certificates<br />
- Trigger when the certificates are about to expire (Which means your auro renew does not work correctly)<br />
- Monitor the certbot version<br />
- Triggers when certbor version is below 0.28<br />
<br />
The certbot version is important, since all certbot versions below 0.28 don't support the ACME-2.0 standard which is required by letsencrypt since the <a href="https://community.letsencrypt.org/t/february-13-2019-end-of-life-for-all-tls-sni-01-validation-support/74209" target="_blank">13-february 2019</a>.<br />
<br />
Whith this you can relax about your ssl certificates, you won't have customers calling you in the morning, that their website(s) have an invalid/expired certificate.<br />
<br />
You can even enhance the ssl monitoring with more Zabbix templates from <a href="https://github.com/a-schild/zabbix-ssl" target="_blank">here</a>.<br />
These allow you to monitor also ftps/imaps/smtps/pop3s and other TLS/SSL secured connections.<br />
<br />
<a href="https://www.aarboard.ch/" target="_blank">We use</a> these in our <a href="https://www.oncloud7.ch/aarboard/Monitoring.html" target="_blank">own environment</a>, to make sure everything runs smoothly and that we are warned of potential problems before the customers notice them.ZorkNikahttp://www.blogger.com/profile/00220798333873847668noreply@blogger.com0tag:blogger.com,1999:blog-5536625962775064923.post-13763372114170716612018-08-31T11:32:00.001+02:002018-08-31T11:32:35.352+02:00Java ffmpeg wrapper jave<h2>
Java ffmpeg wrapper</h2>
In the last months we did some major enhancements in the jave library which can be used from java to analyze/convert audio and video files with the use of ffmpeg.<br />
<br />
The project homepage can be found here <a href="https://github.com/a-schild/jave2">https://github.com/a-schild/jave2</a><br />
<br />
The main changes as to the original package are:<br />
- Support for Windwos 32+64 bit<br />
- Support for Linux 32+64 bit<br />
- Support for OS-X 64bit<br />
- Upgraded to ffmpeg 4.x (From 3.x)<br />
- Enhanced output parsing<br />
- Added options for running the encoding/decoding as a separate thread<br />
- Added to maven central for simpler usage <br />
- Many smaller enhancements<br />
<br />
The project was initially started by Carlo Pelliccia at <a href="http://www.sauronsoftware.it/projects/jave/" target="_blank">http://www.sauronsoftware.it/projects/jave/</a><br />
<br />
You are welcome to contribute to the project with ideas and code.<br />
You can use the github page for this.ZorkNikahttp://www.blogger.com/profile/00220798333873847668noreply@blogger.com0tag:blogger.com,1999:blog-5536625962775064923.post-19024122406054834922018-07-02T08:24:00.003+02:002020-10-21T15:21:51.545+02:00Install Zabbix agent on FreeNAS 11.x<p>There is no official <b>Zabbix Agent</b> binary for <b>FreeNAS</b>, so it has to be compiled from source on another machine.
There are several options to do so, I decided to just spin up a FreeBSD Vagrant VM to build the binary.<br />
This post is based on the post from [1] with some enhancements </p><p><br />
</p><p>For more recent howto see <a href="http://techtuxwords.blogspot.com/2020/10/install-zabbix-agent-on-truenas.html">here</a><br />
</p><h2 id="vagrant-vm">
Vagrant VM</h2>
<h3 id="setup-vm--build-environment">
Setup VM & Build Environment</h3>
<ol>
<li>Create <code class="highlighter-rouge">Vagrantfile</code>:
<div class="language-bash highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code>Vagrant.configure("2") do |config|
config.vm.box = "freebsd/FreeBSD-11.1-STABLE"
config.vm.base_mac = "000000123456"
end
</code></pre>
</div>
</div>
</li>
<li>Start VM: <code class="highlighter-rouge">vagrant up</code></li>
<li>Enter VM: <code class="highlighter-rouge">vagrant ssh</code></li>
<li>Install dependecies:
<div class="language-bash highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code>sudo pkg install -y curl autoconf automake gettext gcc pcre
</code></pre>
</div>
</div>
</li>
</ol>
<h3 id="compile-zabbix-agent">
Compile Zabbix Agent</h3>
<ol>
<li>Download source: https://www.zabbix.com/download_sources#tab:40LTS</li>
<li><div class="language-bash highlighter-rouge">
<div class="highlight">
<pre class="highlight"><strike><code>curl -fsSL "https://sourceforge.net/projects/zabbix/files/ZABBIX%20Latest%20Stable/3.4.14/zabbix-3.4.14.tar.gz/download" | tar zxvf -
cd zabbix-3.4.14</code></strike></pre>
<pre class="highlight"><code><code>curl -fsSL "</code>https://sourceforge.net/projects/zabbix/files/ZABBIX%20Latest%20Stable/4.0.3/zabbix-4.0.3.tar.gz/download</code><code><code>" | tar zxvf -</code></code></pre>
<pre class="highlight"><code><code>cd zabbix-4.0.9</code></code></pre>
</div>
</div>
</li>
<li>Build with TLS support for encryption:
<div class="language-bash highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code>./configure --enable-agent --with-openssl </code><code>--enable-ipv6
sudo make install
</code></pre>
</div>
</div>
</li>
<li>Transfer compiled binary to FreeNAS system:
<div class="language-bash highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code>scp /usr/local/sbin/zabbix_agentd root@<span class="var">$FREENAS_IP</span>:/usr/local/sbin/
</code></pre>
</div>
</div>
</li>
<li>Leave VM: <code class="highlighter-rouge">exit</code></li>
<li>Destroy VM (optional): <code class="highlighter-rouge">vagrant destroy</code></li>
</ol>
<h2 id="freenas">
FreeNAS</h2>
After the <i>zabbix_agentd</i> binary is transferred to the FreeNAS system, it’s time to SSH into it to configure the agent.<br />
<h3 id="zabbix-agent-configuration">
Zabbix Agent Configuration</h3>
<ol>
<li><strike>Add user:
</strike><div class="language-bash highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code><strike>pw groupadd zabbix
pw useradd zabbix -c "Daemon user for Zabbix agent" -d /nonexistent -s /usr/sbin/nologin -w no -g zabbix</strike> </code></pre>
<pre class="highlight"><code>Create zabbix user and group via WebUI, otherwise they won't suvive a reboot</code></pre>
</div>
</div>
</li>
<li>Create <code class="highlighter-rouge">/etc/zabbix_agentd.conf</code>:
<div class="highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code>Server=<span class="var">$ZABBIX_SERVER_IP</span>
ServerActive=<span class="var">$ZABBIX_SERVER_IP</span>
Hostname=<span class="var">$ZABBIX_AGENT_HOSTNAME</span>
LogFile=/tmp/zabbix_agentd.log
</code></pre>
</div>
</div>
</li>
</ol>
<h3 id="daemon-configuration">
Daemon Configuration</h3>
<ol>
<li>Enable daemon:
<div class="language-bash highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code>echo 'zabbix_agentd_enable="YES"' >> /etc/rc.conf
</code></pre>
</div>
</div>
</li>
<li>Create <code class="highlighter-rouge">/etc/rc.d/zabbix_agentd</code>:
<div class="highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code>#!/bin/sh
# PROVIDE: zabbix_agentd
# REQUIRE: DAEMON
# KEYWORD: shutdown
#
# Add the following lines to /etc/rc.conf.local or /etc/rc.conf to
# enable zabbix_agentd:
#
# zabbix_agentd_enable (bool): Set to NO by default. Set it to YES to
# enable zabbix_agentd.
#
. /etc/rc.subr
name="zabbix_agentd"
rcvar=zabbix_agentd_enable
start_precmd="zabbix_precmd"
required_files="/etc/zabbix_agentd.conf"
# read configuration and set defaultsc
load_rc_config "$name"
: ${zabbix_agentd_enable="NO"}
#: ${zabbix_agentd_pre:=/etc/${name}.pre.sh}
zabbix_agentd_conf="/etc/zabbix_agentd.conf"
if [ ! -z "$zabbix_agentd_conf" ] ; then
zabbix_agentd_flags="${zabbix_agentd_flags} -c ${zabbix_agentd_conf}"
required_files=${zabbix_agentd_conf}
fi
zabbix_precmd()
{
if [ ! -z "$zabbix_agentd_pre" ] ; then
if [ -e $zabbix_agentd_pre ] ; then
. $zabbix_agentd_pre
fi
fi
}
command="/usr/local/sbin/${name}"
run_rc_command "$1" run_rc_command "$1"
</code></pre>
</div>
</div>
</li>
<li>Make executable:
<div class="language-bash highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code>chmod +x /etc/rc.d/zabbix_agentd
</code></pre>
</div>
</div>
</li>
<li>Start daemon:
<div class="language-bash highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code>/etc/rc.d/zabbix_agentd start
</code></pre>
</div>
</div>
</li>
<li>Make config files persistent and survive reboots:
<div class="language-bash highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code>cp /etc/rc.conf /conf/base/etc/
cp /etc/rc.d/zabbix_agentd /conf/base/etc/rc.d/
cp /etc/zabbix_agentd.* /conf/base/etc/</code></pre>
<pre class="highlight"><code> </code></pre>
</div>
</div>
</li>
</ol>
<h3 id="daemon-configuration">
Exit vagrant</h3>
<div id="daemon-configuration">
in the ssh sesion type: exit</div>
<div id="daemon-configuration">
vagrant destroy</div>
<h3 id="daemon-configuration">
Zabbix configuration</h3>
<pre class="highlight"><code>Use the template from the zabbix wiki for the host monitoring</code></pre>
<pre class="highlight"><code><a href="http://zabbix.org/wiki/File:Template_OS_FreeNAS.xml">http://zabbix.org/wiki/File:Template_OS_FreeNAS.xml</a></code></pre>
<hr />
<ol>
<li><a href="https://docs.j7k6.org/freenas-zabbix-agent/">https://docs.j7k6.org/freenas-zabbix-agent/</a> </li>
<li><a href="https://blag.nullteilerfrei.de/2016/11/26/zabbix-3-0-agent-on-freebsd/">https://blag.nullteilerfrei.de/2016/11/26/zabbix-3-0-agent-on-freebsd/</a></li>
<li><a href="https://www.haphazard.io/blog/install-nagios-nrpe-on-freenas/">https://www.haphazard.io/blog/install-nagios-nrpe-on-freenas/</a></li>
</ol>
ZorkNikahttp://www.blogger.com/profile/00220798333873847668noreply@blogger.com1tag:blogger.com,1999:blog-5536625962775064923.post-46689280889414577562018-04-11T09:12:00.001+02:002018-04-11T09:12:28.453+02:00Updated LDAP server for Innovaphone<h2>
Updated LDAP server for Innovaphone devices</h2>
<br />
Last year <a href="http://techtuxwords.blogspot.ch/2017/10/small-ldap-server-for-innovaphone-pbx.html" target="_blank">we did publish</a> our small ldap server as opensource on git hub.<br />
In the past months we did many enhancements, which added text search capability, more number fields and better support for varios DECT platforms.<br />
<br />
If you already use it, we strongly suggest that you upgrade to the <a href="https://github.com/a-schild/inno-thinyldap" target="_blank">new 2.2 release</a>.<br />
<br />
If you are providing a hosted environment for your clients, then we have a closed source version of the same software, which can handle tenants for your different clients. Just contact<a href="mailto:info@aarboard.ch" target="_blank"> info@aarboard.ch</a> for a quote. <br />
<br />ZorkNikahttp://www.blogger.com/profile/00220798333873847668noreply@blogger.com0tag:blogger.com,1999:blog-5536625962775064923.post-39178605548389713522018-03-14T16:58:00.002+01:002018-03-14T16:58:20.786+01:00Monitor Netgear ReadyNAS with Zabbix<h2>
Zabbix template for Netgear ReadyNAS </h2>
Monitoring devices with Zabbix is a simple thing, at least when you have a matching template for your device.<br />
<br />
For Netgear ReadyNAS devices there exist many different templates, but most are outdated and no longer support the current 6.9.x firmware.<br />
<br />
We integrated "all" ideas found in the other templates to provide a easy to install/use template for your device.<br />
<h3>
Features </h3>
<ul>
<li>LLD of disks, fans, temperature sensors, volumes, partitions, inetrfaces and processors</li>
<li>Creation of graph and triggers</li>
<li>No need to deploy MIB files to servers/agents, we work with direct OID's</li>
</ul>
<br />
<br />
The template and install instructions can be found here on <a href="https://github.com/a-schild/zabbix-readynas" target="_blank">Github link</a><br />
<br />
Please open a issue in Github if you need more features or have enhancements you can provide. ZorkNikahttp://www.blogger.com/profile/00220798333873847668noreply@blogger.com0tag:blogger.com,1999:blog-5536625962775064923.post-40600482523227029772017-10-02T21:34:00.000+02:002018-02-12T12:04:35.085+01:00Small LDAP server for Innovaphone PBXThe <a href="http://www.innovaphone.de/" target="_blank">innovaphone </a>PBX series are small hardware (or virtual systems) which are very powerful and customizable to almost all user requirements.<br />
<br />
They also use Internet standard where ever possible.<br />
<br />
For number reverse look up and address books, the preferred method is ldap.<br />
<br />
In small installations you usually don't have your LDAP server configured to maintain all your contacts and phone numbers, so you are in fact missing a simple address book for your solution.<br />
Of course there exist large ldap servers, like <a href="https://www.estos.de/produkte/metadirectory" target="_blank">Estos Metadirectory</a> and others, but for many use cases they are just oversized and too expensive.<br />
<br />
This gap is now filled with the open source project "inno-thinyldap" which can be found on <a href="https://github.com/a-schild/inno-thinyldap" target="_blank">github</a>.<br />
<br />
It has two main functions:<br />
- Forward and reverse look up of numbers against a built in mysql database<br />
- Reverse look up of phone numbers against the tel.search.ch directory<br />
<br />
The local mysql address book can be maintained by uploading/download xlsx file containing your contacts and phone numbers.<br />
<br />
Give it a try and tell me what you think about it.<br />
<br />
PS: If you need the same thing, but usable for hosting/multiple clients in the same installation, get in touch with <a href="mailto:a.schild@aarboard.ch">a.schild@aarboard.ch</a> ZorkNikahttp://www.blogger.com/profile/00220798333873847668noreply@blogger.com0tag:blogger.com,1999:blog-5536625962775064923.post-73881349363567038332017-06-21T10:00:00.001+02:002017-06-22T09:39:11.168+02:00JSVC fails with error 11 after latest linux kernel Upgrades on debian/ubuntuThis morning, after doing some apt-get update/upgrades on various debian systems, we noticed that many of our java services did no longer work.<br />
Since we use it to handle all our tomcat instances on many many servers, the impact is heavy.No single tomcat did run this morning...<br />
<br />
Looking into the tomcat logs, we did see this message:<br />
<span style="font-family: "courier new" , "courier" , monospace;">Service killed by signal 11</span><br />
<br />
After some more investigations, it looks like the problem is related to the new kernel version installed in the upgrade process.<br />
<br />
Google didn't find much about this, but the more important ones are here:<br />
<ul>
<li><a href="https://www.mail-archive.com/debian-bugs-dist@lists.debian.org/msg1525389.html">https://www.mail-archive.com/debian-bugs-dist@lists.debian.org/msg1525389.html</a></li>
<li><a href="https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=865343">https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=865343</a></li>
<li><a href="https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=865311">https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=865311</a> </li>
<li><a href="https://community.ubnt.com/t5/UniFi-Wireless/unifi-won-t-start-after-apt-get-upgrade-and-reboot/td-p/1967641">https://community.ubnt.com/t5/UniFi-Wireless/unifi-won-t-start-after-apt-get-upgrade-and-reboot/td-p/1967641</a></li>
</ul>
<strike>So the solution for now, is either switch to not using jsvc to start your services, or use a older or a "unstable" kernel.</strike><br />
<strike><br /></strike>
<strike>The kernel causing the problems is </strike><br />
<pre><strike>3.16.0-4-amd64 #1 SMP Debian 3.16.43-2+deb8u1 (2017-06-18) x86_64</strike></pre>
<pre><strike> </strike></pre>
<strike>With the older one it does work
</strike><br />
<pre><strike>3.16.0-4-amd64 #1 SMP Debian 3.16.43-2 (2017-04-30) x86_64</strike></pre>
<pre><strike> </strike></pre>
<strike>To switch back to the older kernel just do this, and reboot your system:
</strike><br />
<pre><strike>apt install linux-image-3.16.0-4-amd64=3.16.43-2 </strike></pre>
<pre><strike> </strike></pre>
<b>Reverting back to a older kernel is discouraged, since this does not solve the security problem.</b><br />
<br />
Fortunately there is a very simple work arround for it.<br />
When you start jsvc, just specify it to use a larger stack.<br />
For tomcat you can put this in your startup file, so the daemon.sh takes the new options for jsvc.<br />
<pre> </pre>
<pre>export JSVC_OPTS=-Xss1280k</pre>
<br />
Thanks to <a href="https://community.ubnt.com/t5/UniFi-Wireless/IMPORTANT-Debian-Ubuntu-users-MUST-READ-Updated-06-21/td-p/1968252">https://community.ubnt.com/t5/UniFi-Wireless/IMPORTANT-Debian-Ubuntu-users-MUST-READ-Updated-06-21/td-p/1968252</a>
ZorkNikahttp://www.blogger.com/profile/00220798333873847668noreply@blogger.com0tag:blogger.com,1999:blog-5536625962775064923.post-46657285289824223182017-06-19T16:38:00.002+02:002017-06-19T16:38:49.174+02:00Installing/running Debian stretsch inside kvm debian jessieInstalling or upgrading to a Debian stretch (Debian 9) edition should be a "no problem" case for most platforms.<br />
<br />
Unfortunally running stretch in a KVM/QEMU environment based on Debian jessie isn't "just" working.<br />
<br />
We did try to upgrade a existing Debian Jessie VM to stretch with the usual steps.<br />
The upgrade itself works very fine and flawless as known from Debian systems.<br />
But after rebooting the system, we did start getting errors in the guest, most of the time it did not even boot correctly.<br />
<br />
In the host logfile we did see these messages in syslog:<br />
<br />
<span style="font-family: "Courier New",Courier,monospace;">kvm: zapping shadow pages for mmio generation wraparound</span><br />
<span style="font-family: "Courier New",Courier,monospace;">vcpu0 unhandled rdmsr: 0x34</span><br /><br />
In the log of the guest, we did see these stack traces:<br />
<br />
<span style="font-family: "Courier New",Courier,monospace;">Jun 19 15:40:18 sv54 kernel: [ 0.000000] Linux version 4.9.0-3-amd64 (debian-kernel@lists.debian.org) (gcc version 6.3.0 20170516 (Debian 6.3.0-18) ) #1 SMP Debian 4.9.30-2 (2017-06-12)<br />Jun 19 15:40:18 sv54 kernel: [ 0.000000] Command line: BOOT_IMAGE=/boot/vmlinuz-4.9.0-3-amd64 root=UUID=fb8d9106-4421-4e85-af6f-8c0561bb2b25 ro quiet<br />Jun 19 15:40:18 sv54 kernel: [ 0.000000] ------------[ cut here ]------------<br />Jun 19 15:40:18 sv54 kernel: [ 0.000000] WARNING: CPU: 0 PID: 0 at /build/linux-FT3UnK/linux-4.9.30/arch/x86/kernel/fpu/xstate.c:593 fpu__init_system_xstate+0x53b/0x981<br />Jun 19 15:40:18 sv54 kernel: [ 0.000000] XSAVE consistency problem, dumping leaves<br />Jun 19 15:40:18 sv54 kernel: [ 0.000000] Modules linked in:<br />Jun 19 15:40:18 sv54 kernel: [ 0.000000] CPU: 0 PID: 0 Comm: swapper Not tainted 4.9.0-3-amd64 #1 Debian 4.9.30-2<br />Jun 19 15:40:18 sv54 kernel: [ 0.000000] 0000000000000000 ffffffff87f28634 ffffffff88803e08 0000000000000000<br />Jun 19 15:40:18 sv54 kernel: [ 0.000000] ffffffff87c76eae 000000000000000a ffffffff88803e60 0000000000000340<br />Jun 19 15:40:18 sv54 kernel: [ 0.000000] ffffffff88803e90 ffffffff88803e9c 0000000000000100 ffffffff87c76f2f<br />Jun 19 15:40:18 sv54 kernel: [ 0.000000] Call Trace:<br />Jun 19 15:40:18 sv54 kernel: [ 0.000000] [<ffffffff87f28634>] ? dump_stack+0x5c/0x78<br />Jun 19 15:40:18 sv54 kernel: [ 0.000000] [<ffffffff87c76eae>] ? __warn+0xbe/0xe0<br />Jun 19 15:40:18 sv54 kernel: [ 0.000000] [<ffffffff87c76f2f>] ? warn_slowpath_fmt+0x5f/0x80<br />Jun 19 15:40:18 sv54 kernel: [ 0.000000] [<ffffffff87c72754>] ? xfeature_size+0x5a/0x78<br />Jun 19 15:40:18 sv54 kernel: [ 0.000000] [<ffffffff88947243>] ? fpu__init_system_xstate+0x53b/0x981<br />Jun 19 15:40:18 sv54 kernel: [ 0.000000] [<ffffffff87f586e6>] ? msr_clear_bit+0x36/0xa0<br />Jun 19 15:40:18 sv54 kernel: [ 0.000000] [<ffffffff889468dc>] ? fpu__init_system+0x208/0x30b<br />Jun 19 15:40:18 sv54 kernel: [ 0.000000] [<ffffffff88942fea>] ? setup_arch+0xb8/0xcc6<br />Jun 19 15:40:18 sv54 kernel: [ 0.000000] [<ffffffff87d7a24e>] ? printk+0x57/0x73<br />Jun 19 15:40:18 sv54 kernel: [ 0.000000] [<ffffffff88938120>] ? early_idt_handler_array+0x120/0x120<br />Jun 19 15:40:18 sv54 kernel: [ 0.000000] [<ffffffff88938bbf>] ? start_kernel+0xab/0x463<br />Jun 19 15:40:18 sv54 kernel: [ 0.000000] [<ffffffff88938120>] ? early_idt_handler_array+0x120/0x120<br />Jun 19 15:40:18 sv54 kernel: [ 0.000000] [<ffffffff88938408>] ? x86_64_start_kernel+0x14c/0x170<br />Jun 19 15:40:18 sv54 kernel: [ 0.000000] ---[ end trace 44d08096f31f4f03 ]---</span><br />
<br />
and<br />
<br />
<span style="font-family: "Courier New",Courier,monospace;">Jun 19 15:40:18 sv54 kernel: [ 0.387100] WARNING: CPU: 2 PID: 1 at /build/linux-FT3UnK/linux-4.9.30/arch/x86/include/asm/fpu/internal.h:368 fpu__clear+0x179/0x1b0<br />Jun 19 15:40:18 sv54 kernel: [ 0.387101] Modules linked in:<br />Jun 19 15:40:18 sv54 kernel: [ 0.387103] CPU: 2 PID: 1 Comm: swapper/0 Tainted: G W 4.9.0-3-amd64 #1 Debian 4.9.30-2<br />Jun 19 15:40:18 sv54 kernel: [ 0.387103] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.7.5-20140531_083030-gandalf 04/01/2014<br />Jun 19 15:40:18 sv54 kernel: [ 0.387104] 0000000000000000 ffffffff87f28634 0000000000000000 0000000000000000<br />Jun 19 15:40:18 sv54 kernel: [ 0.387105] ffffffff87c76eae ffff9ec076158040 ffff9ec076158b40 ffff9ec072329400<br />Jun 19 15:40:18 sv54 kernel: [ 0.387106] ffffffff88869da0 ffff9ec072354400 ffff9ec076158758 ffffffff87c30fc9<br />Jun 19 15:40:18 sv54 kernel: [ 0.387107] Call Trace:<br />Jun 19 15:40:18 sv54 kernel: [ 0.387110] [<ffffffff87f28634>] ? dump_stack+0x5c/0x78<br />Jun 19 15:40:18 sv54 kernel: [ 0.387112] [<ffffffff87c76eae>] ? __warn+0xbe/0xe0<br />Jun 19 15:40:18 sv54 kernel: [ 0.387113] [<ffffffff87c30fc9>] ? fpu__clear+0x179/0x1b0<br />Jun 19 15:40:18 sv54 kernel: [ 0.387114] [<ffffffff87e0914c>] ? flush_old_exec+0x5bc/0x6b0<br />Jun 19 15:40:18 sv54 kernel: [ 0.387116] [<ffffffff87e5df52>] ? load_elf_binary+0x3c2/0x1600<br />Jun 19 15:40:18 sv54 kernel: [ 0.387117] [<ffffffff87e087f0>] ? search_binary_handler+0xa0/0x1c0<br />Jun 19 15:40:18 sv54 kernel: [ 0.387118] [<ffffffff87e5d734>] ? load_script+0x204/0x230<br />Jun 19 15:40:18 sv54 kernel: [ 0.387118] [<ffffffff87dfe0da>] ? __check_object_size+0xfa/0x1d8<br />Jun 19 15:40:18 sv54 kernel: [ 0.387119] [<ffffffff87e093c8>] ? copy_strings.isra.25+0x188/0x450<br />Jun 19 15:40:18 sv54 kernel: [ 0.387120] [<ffffffff87e087f0>] ? search_binary_handler+0xa0/0x1c0<br />Jun 19 15:40:18 sv54 kernel: [ 0.387121] [<ffffffff87e09f0a>] ? do_execveat_common.isra.37+0x5aa/0x790<br />Jun 19 15:40:18 sv54 kernel: [ 0.387123] [<ffffffff881f8d20>] ? rest_init+0x80/0x80<br />Jun 19 15:40:18 sv54 kernel: [ 0.387124] [<ffffffff87e0a118>] ? do_execve+0x28/0x30<br />Jun 19 15:40:18 sv54 kernel: [ 0.387125] [<ffffffff881f8d70>] ? kernel_init+0x50/0x100<br />Jun 19 15:40:18 sv54 kernel: [ 0.387126] [<ffffffff882064f5>] ? ret_from_fork+0x25/0x30<br />Jun 19 15:40:18 sv54 kernel: [ 0.387127] ---[ end trace 44d08096f31f4f07 ]---<br />Jun 19 15:40:18 sv54 kernel: [ 0.387363] ------------[ cut here ]------------<br />Jun 19 15:40:18 sv54 kernel: [ 0.387365] WARNING: CPU: 2 PID: 1 at /build/linux-FT3UnK/linux-4.9.30/arch/x86/include/asm/fpu/internal.h:353 fpu__copy+0x140/0x190<br />Jun 19 15:40:18 sv54 kernel: [ 0.387366] Modules linked in:<br />Jun 19 15:40:18 sv54 kernel: [ 0.387367] CPU: 2 PID: 1 Comm: init Tainted: G W 4.9.0-3-amd64 #1 Debian 4.9.30-2<br />Jun 19 15:40:18 sv54 kernel: [ 0.387367] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.7.5-20140531_083030-gandalf 04/01/2014<br />Jun 19 15:40:18 sv54 kernel: [ 0.387368] 0000000000000000 ffffffff87f28634 0000000000000000 0000000000000000<br />Jun 19 15:40:18 sv54 kernel: [ 0.387369] ffffffff87c76eae ffff9ec0723e7ec0 ffff9ec076158b40 ffff9ec0723e7e80<br />Jun 19 15:40:18 sv54 kernel: [ 0.387370] 0000000000000000 0000000000000000 00007f7cfecd79d0 ffffffff87c30a90<br />Jun 19 15:40:18 sv54 kernel: [ 0.387371] Call Trace:<br />Jun 19 15:40:18 sv54 kernel: [ 0.387373] [<ffffffff87f28634>] ? dump_stack+0x5c/0x78<br />Jun 19 15:40:18 sv54 kernel: [ 0.387374] [<ffffffff87c76eae>] ? __warn+0xbe/0xe0<br />Jun 19 15:40:18 sv54 kernel: [ 0.387375] [<ffffffff87c30a90>] ? fpu__copy+0x140/0x190<br />Jun 19 15:40:18 sv54 kernel: [ 0.387376] [<ffffffff87c74490>] ? copy_process.part.33+0x1a0/0x1c00<br />Jun 19 15:40:18 sv54 kernel: [ 0.387377] [<ffffffff87dfe0da>] ? __check_object_size+0xfa/0x1d8<br />Jun 19 15:40:18 sv54 kernel: [ 0.387379] [<ffffffff87f56988>] ? strncpy_from_user+0x48/0x160<br />Jun 19 15:40:18 sv54 kernel: [ 0.387379] [<ffffffff87e0744d>] ? cp_new_stat+0x14d/0x180<br />Jun 19 15:40:18 sv54 kernel: [ 0.387381] [<ffffffff87c760d3>] ? _do_fork+0xe3/0x3f0<br />Jun 19 15:40:18 sv54 kernel: [ 0.387381] [<ffffffff87e074b9>] ? SYSC_newstat+0x39/0x60<br />Jun 19 15:40:18 sv54 kernel: [ 0.387383] [<ffffffff87c03b1c>] ? do_syscall_64+0x7c/0xf0<br />Jun 19 15:40:18 sv54 kernel: [ 0.387384] [<ffffffff8820632f>] ? entry_SYSCALL64_slow_path+0x25/0x25<br />Jun 19 15:40:18 sv54 kernel: [ 0.387384] ---[ end trace 44d08096f31f4f08 ]---<br />Jun 19 15:40:18 sv54 kernel: [ 0.387420] ------------[ cut here ]------------<br />Jun 19 15:40:18 sv54 kernel: [ 0.387422] WARNING: CPU: 2 PID: 1 at /build/linux-FT3UnK/linux-4.9.30/arch/x86/include/asm/fpu/internal.h:353 __switch_to+0x66a/0x6c0<br />Jun 19 15:40:18 sv54 kernel: [ 0.387422] ------------[ cut here ]------------<br />Jun 19 15:40:18 sv54 kernel: [ 0.387423] Modules linked in:<br />Jun 19 15:40:18 sv54 kernel: [ 0.387425] WARNING: CPU: 3 PID: 0 at /build/linux-FT3UnK/linux-4.9.30/arch/x86/include/asm/fpu/internal.h:368 __switch_to+0x415/0x6c0<br />Jun 19 15:40:18 sv54 kernel: [ 0.387426] CPU: 2 PID: 1 Comm: init Tainted: G W 4.9.0-3-amd64 #1 Debian 4.9.30-2<br />Jun 19 15:40:18 sv54 kernel: [ 0.387427] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.7.5-20140531_083030-gandalf 04/01/2014<br />Jun 19 15:40:18 sv54 kernel: [ 0.387427] Modules linked in:<br />Jun 19 15:40:18 sv54 kernel: [ 0.387428] 0000000000000000 ffffffff87f28634 0000000000000000 0000000000000000<br />Jun 19 15:40:18 sv54 kernel: [ 0.387430] ffffffff87c76eae ffff9ec0762401c0 ffff9ec076158040 ffff9ec076240cc0<br />Jun 19 15:40:18 sv54 kernel: [ 0.387431] ffff9ec0762401c0 0000000000000002 ffff9ec076158a80 ffffffff87c24aaa<br />Jun 19 15:40:18 sv54 kernel: [ 0.387432] Call Trace:<br />Jun 19 15:40:18 sv54 kernel: [ 0.387432] ---[ end trace 44d08096f31f4f09 ]---</span><br />
<br />
After some research we did find out, that there is a bug in the QEMU/KVM packages as provided by jessie stable repositories.<br />
<br />
To solve the problem, you have to install more recent QEMU/KVM packages, and the best way to get them for stretch is to add the jessie backports to your sources.list<br />
<br />
<span style="font-family: "Courier New",Courier,monospace;">deb http://ftp.debian.org/debian jessie-backports main</span><br /><br />After the usual apt-get update just install the qemu-kvm and related packages in the 2.8xxx version, instead of the 2.1xxxx releases.<br />
<br />
After a reboot of your physical server, you can now enjoy debian stretch in your guestsZorkNikahttp://www.blogger.com/profile/00220798333873847668noreply@blogger.com0tag:blogger.com,1999:blog-5536625962775064923.post-65245507543259501232017-06-06T10:16:00.001+02:002017-06-06T10:16:21.247+02:00Purge and remove backup files in Bareos / BaculaBareos / Bacula are very powerfull backup solutions for enterprises<br />
<br />
When using backup to disk, one of the more nasty maintenance tasks, is removing old backup files.<br />
To help you with this, you can use <a href="https://github.com/a-schild/bacula-purge-unused" target="_blank">this script</a> to remove expired backup files, and also backup files which contain error-only backups.<br />
<br />
It is based on the code from <a href="http://heim.ifi.uio.no/kjetilho/hacks/#bacula-purge-unused" target="_blank">Kjetil </a>and has been modified to also woth with bareos 15 and mysql databases.<br />
<br />
Patches and enhancements are welcome on the <a href="https://github.com/a-schild/bacula-purge-unused" target="_blank">github </a>platform.ZorkNikahttp://www.blogger.com/profile/00220798333873847668noreply@blogger.com0tag:blogger.com,1999:blog-5536625962775064923.post-28302777772462694382017-05-24T09:04:00.001+02:002017-05-24T09:04:55.035+02:00Using letsencrypt certificates with Collabnet Subversion EdgeWith the <a href="https://letsencrypt.org/" target="_blank">letsencrypt </a>CA you can create ssl certificates to protect your http servers with a valid certificate.<br />
<br />
These certificates are valid 90 days and the can be auto renewed, so your services won't interrupt.<br />
<br />
For normal apache / nginx installations there are plenty of documentations on how to install and use such certificates.<br />
<br />
Unfortunately with<a href="https://www.collab.net/products/subversion" target="_blank"> subversion edge</a>, it does not just work out of the box, but it uses a apache http server for http/https communication.<br />
<br />
So what's the problem?<br />
<br />
Let's look at a standard subversion edge installation under debian:<br />
<ul>
<li>The certificates are stored in /opt/csvn/data/conf in the files server.crt and server.key</li>
<li>The configuration for the ssl certificates are in the csvn_main_httpd.conf file, which is generated at each restart</li>
<li>In the csvn_main_httpd.conf file we only have the two server.crt and server.key files referenced, but not the required intermediate certificate chain</li>
</ul>
<br />
The first thing to do is generate a ssl certificate for your server.<br />
The http server root points to /var/www/html, so you can use that folder to generate your certificates<br />
<br />
<pre class="prettyprint prettified"><span style="font-family: "courier new" , "courier" , monospace;"><span class="pln">certbot certonly </span><span class="pun">--</span><span class="pln">webroot </span><span class="pun">-</span><span class="pln">w </span><span class="pun">/var/www/html</span><span class="pln"> </span><span class="pun">-</span><span class="pln">d svn.example.com</span></span></pre>
This generates the certificates in /etc/letsencrypt/live/svn.example.com<br />
<br />
To use them, you can now delete the two server.crt and server.key files in /opt/csvn/data/conf and create symbolic links to these files<br />
<br />
<pre class="prettyprint prettified">server.crt -> /etc/letsencrypt/live/svn.example.com/cert.pem</pre>
<br />
<pre class="prettyprint prettified">server.key -> /etc/letsencrypt/live/svn.example.com/privkey.pem</pre>
<br />
But what about the SSLCertificateChainFile /etc/letsencrypt/live/svn.example.com/fullchain.pem file?<br />
You can't add it to csvn_main_httpd.conf since this file is regenegated on each restart.<br />
But fortunally you can add it into the https special config, where the chiper config is stored.<br />
So just add it into the ssl_httpd.conf file<br />
<br />
Now we have everything together and could start the https svn server.<br />
Unfortunately this will fail with a error message like:<br />
<br />
<pre class="prettyprint prettified">ERROR errors.GrailsExceptionResolver -</pre>
<pre class="prettyprint prettified"> FileNotFoundException occurred when processing request: </pre>
<pre class="prettyprint prettified">[POST] /csvn/
/opt/csvn/data/conf/server.crt (Permission denied). Stacktrace follows:
java.io.FileNotFoundException: /opt/csvn/data/conf/server.crt (Permission denied)
at java.io.FileOutputStream.open(FileOutputStream.java:270)
at java.io.FileOutputStream.<init>(FileOutputStream.java:213)
at java.io.FileWriter.<init>(FileWriter.java:107)</pre>
<br />
<br />
Ok, so you are running subversion as non-root as recommended. (If not, then rethink what you are doing and reinstall subversion as a standard user)<br />
<br />
To allow the subversion user to access the ssl certificates of letsencrypt, the simplest way is to add the subversion user to the ssl-cert group, and give the group rx access to the certificates in /etc/letsencrypt/live and /etc/letsencrypt/archive<br />
<br />
Once this is done, you should be able to start the svn server with active letsenrcypt ssl certificates.<br />
What remains to be done is the periodic renewal of the certificates, which is widely described in the Internet.<br />
What you have to do, is to restart the https service when a new certificate is generated. Usually you can do this in the renew script.ZorkNikahttp://www.blogger.com/profile/00220798333873847668noreply@blogger.com1