<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Web Applications on shocksolution.com</title><link>https://shocksolution.com/tags/web-applications/</link><description>Recent content in Web Applications on shocksolution.com</description><generator>Hugo</generator><language>en-us</language><lastBuildDate>Wed, 05 May 2021 20:37:05 +0000</lastBuildDate><atom:link href="https://shocksolution.com/tags/web-applications/index.xml" rel="self" type="application/rss+xml"/><item><title>Multi-Page Blueprints for Confluence</title><link>https://shocksolution.com/posts/multi-page-blueprints-for-confluence/</link><pubDate>Wed, 05 May 2021 20:37:05 +0000</pubDate><guid>https://shocksolution.com/posts/multi-page-blueprints-for-confluence/</guid><description>&lt;p&gt;A free demo app is available in the Atlassian Marketplace which supports multi-page blueprints for Confluence. This app works around numerous bugs in the official Atlassian blueprint tutorials and a key Atlassian API bug.&lt;/p&gt;&#10;&lt;h2 id="background-on-confluence"&gt;Background on Confluence&lt;/h2&gt;&#10;&lt;p&gt;&lt;a href="https://%3Cwww.atlassian.com/software/confluence%3E"&gt;Confluence&lt;/a&gt; is one of the leading enterprise wiki products. Its built-in feature set is already very powerful, and it can be extended with &lt;a href="https://marketplace.atlassian.com/addons/app/confluence"&gt;applications available in the Atlassian Marketplace&lt;/a&gt;. You can also write your own applications for private, internal use. Atlassian provides the &lt;a href="https://bitbucket.org/atlassian/atlassian-connect-express/src/master/"&gt;atlassian-connect-express toolkit for building apps with Node.js&lt;/a&gt;, which reduces development time and effort. They also provide a number of &lt;a href="https://bitbucket.org/atlassianlabs/workspace/projects/ATL"&gt;sample projects for Jira and Confluence apps&lt;/a&gt; on Bitbucket. Unfortunately, many of these examples are obsolete or deprecated, and do not function correctly with the latest version of atlassian-connect-express or the latest release of Confluence and Jira.&lt;/p&gt;</description></item><item><title>Node.js: Connecting to MySQL on a socket with Sequelize</title><link>https://shocksolution.com/posts/node-js-connecting-to-mysql-on-a-socket-with-sequelize/</link><pubDate>Thu, 22 Apr 2021 18:54:25 +0000</pubDate><guid>https://shocksolution.com/posts/node-js-connecting-to-mysql-on-a-socket-with-sequelize/</guid><description>&lt;p&gt;According to its official description, &amp;ldquo;&lt;a href="https://sequelize.org/master/index.html"&gt;Sequelize is a promise-based Node.js ORM for Postgres, MySQL, MariaDB, SQLite and Microsoft SQL Server.&lt;/a&gt;&amp;rdquo; Sequelize is widely used in Node.js web applications to abstract the database layer. I recently found a &amp;ldquo;corner case&amp;rdquo; for Sequelize which is possible to accomplish, but is not well documented anywhere on the web. I need to use Sequelize to connect to a MySQL server via a UNIX socket. I&amp;rsquo;m developing some plugins for Confluence that use the &lt;a href="https://bitbucket.org/atlassian/atlassian-connect-express/src/master/"&gt;atlassian-connect-express&lt;/a&gt; toolkit, which has a datastore that wraps Sequelize. The way Atlassian has chosen to wrap Sequelize is rather unfortunate, probably because they are trying to maintain backwards compatibility with JugglingDB. Essentially, the Atlassian Connect Express only looks at the URL, and ignores any option passed to Sequelize. Therefore, you have to pass everything you need via the URL, and this is where it&amp;rsquo;s tricky. Here&amp;rsquo;s the form of the URL that you need to connect to MySQL via a UNIX socket with Sequelize:&lt;/p&gt;</description></item><item><title>Alert Policies for Log Metrics on Google Stackdriver Monitoring</title><link>https://shocksolution.com/posts/alert-policies-for-log-metrics-on-google-stackdriver-monitoring/</link><pubDate>Tue, 08 Sep 2020 16:31:08 +0000</pubDate><guid>https://shocksolution.com/posts/alert-policies-for-log-metrics-on-google-stackdriver-monitoring/</guid><description>&lt;p&gt;Google Cloud Operations, formerly known as Stackdriver Logging and Monitoring, can be very confusing to set up. It&amp;rsquo;s easy to monitor something simple, but more complex cases quickly get confusing. One of the more flexible but confusing types of alert policies in Stackdriver Monitoring is a Logs-Based Metrics policy, which gives you the ability to monitor entries in Stackdriver Logging.&lt;/p&gt;&#10;&lt;h2 id="create-a-logs-based-metric"&gt;Create a Logs-Based Metric&lt;/h2&gt;&#10;&lt;p&gt;The first step is to go to Stackdriver (Operations) Logging and create a user-defined metric. Go to the Logs Viewer and build a query to return the subset of log entries that you want to monitor (the details of query building are beyond the scope of this article). As of Sept. 2020, I highly recommend enabling the Preview Mode of the Logs Viewer interface, which is much better at guiding you through the process of building the query. If you must use the Classic interface, click the little black arrow at the right side of the filter box, near the top of the Logs Viewer screen. Select &amp;ldquo;Convert to advanced filter&amp;rdquo; from the drop-down menu, and &lt;a href="https://cloud.google.com/logging/docs/view/advanced-queries"&gt;create an advanced filter using the query language&lt;/a&gt;. Once you have created the right filter (query) that selects the log entries that you want to monitor, proceed to the next step:&lt;/p&gt;</description></item><item><title>curl or libcurl: SSL certificate problem: unable to get local issuer certificate</title><link>https://shocksolution.com/posts/curl-or-libcurl-ssl-unable-to-get-local-issuer-certificate/</link><pubDate>Tue, 10 Mar 2020 17:00:17 +0000</pubDate><guid>https://shocksolution.com/posts/curl-or-libcurl-ssl-unable-to-get-local-issuer-certificate/</guid><description>&lt;p&gt;curl, or an application that uses libcurl, may have a problem with an SSL certificate that works fine when using a web browser to access the same URL. Typical error output from curl looks like this:&lt;/p&gt;&#10;&lt;div class="code-block"&gt;&#10; &lt;button class="code-copy" type="button" hidden aria-label="Copy code to clipboard"&gt;&#10; &lt;span class="code-copy-label" aria-hidden="true"&gt;Copy&lt;/span&gt;&#10; &lt;/button&gt;&#10; &lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ curl -v https://my-subdomain.mysecuresite.com&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Trying xxx.xxx.xxx.xxx:443…&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; TCP_NODELAY set&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Connected to my-subdomain.mysecuresite.com (xxx.xxx.xxx.xxx) port 443 (#0)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ALPN, offering h2&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ALPN, offering http/1.1&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; successfully set certificate verify locations:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; CAfile: /etc/ssl/certs/ca-certificates.crt&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; CApath: none&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; TLSv1.3 (OUT), TLS handshake, Client hello (1):&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; TLSv1.3 (IN), TLS handshake, Server hello (2):&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; TLSv1.2 (IN), TLS handshake, Certificate (11):&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; TLSv1.2 (OUT), TLS alert, unknown CA (560):&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; SSL certificate problem: unable to get local issuer certificate&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Closing connection 0&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; curl: (60) SSL certificate problem: unable to get local issuer certificate&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; More details here: https://curl.haxx.se/docs/sslcerts.html &#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; curl failed to verify the legitimacy of the server and therefore could not&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; establish a secure connection to it. To learn more about this situation and&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; how to fix it, please visit the web page mentioned above.&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&#10; &lt;/div&gt;&lt;h2 id="troubleshooting-strategy"&gt;Troubleshooting Strategy&lt;/h2&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;A good starting point for any SSL error on a public-facing URL is to &lt;a href="https://%3Cwww.ssllabs.com/ssltest/%3E"&gt;analyze the URL at SSL Labs&lt;/a&gt;.&lt;/li&gt;&#10;&lt;li&gt;Does the error happen for all certificates issued by a specific Certificate Authority (CA)? If so, the system running curl may need to have a root certificate for that CA added or updated in its certificate repository. That&amp;rsquo;s a relatively rare problem, but might occur if the system running curl is very old. There&amp;rsquo;s a &lt;a href="https://stackoverflow.com/questions/24611640/curl-60-ssl-certificate-unable-to-get-local-issuer-certificate"&gt;comprehensive thread about this issue on Stack Overflow&lt;/a&gt;.&lt;/li&gt;&#10;&lt;li&gt;If the error only happens for one specific site, it&amp;rsquo;s likely that the site is missing an intermediate certificate. The command to diagnose this issue is also found in that Stack Overflow thread:&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;div class="code-block"&gt;&#10; &lt;button class="code-copy" type="button" hidden aria-label="Copy code to clipboard"&gt;&#10; &lt;span class="code-copy-label" aria-hidden="true"&gt;Copy&lt;/span&gt;&#10; &lt;/button&gt;&#10; &lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;openssl s_client -connect myhost.com:443 -servername myhost.com -showcerts&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&#10; &lt;/div&gt;&lt;p&gt;The output should show a series of certificates, starting with the site certificate, and ending with the root certificate for the Certification Authority. If this chain only shows the site certificate, that&amp;rsquo;s the problem.&lt;/p&gt;</description></item><item><title>openssl unable to read/load/import SSL private key from GoDaddy</title><link>https://shocksolution.com/posts/openssl-unable-to-read-load-import-ssl-private-key-from-godaddy/</link><pubDate>Mon, 02 Dec 2019 13:24:00 +0000</pubDate><guid>https://shocksolution.com/posts/openssl-unable-to-read-load-import-ssl-private-key-from-godaddy/</guid><description>&lt;p&gt;&lt;a href="https://%3C%3Cwww.openssl.org/&amp;amp;gt%3E;"&gt;openssl&lt;/a&gt; is the standard open-source, command-line tool for manipulating SSL/TLS certificates on Linux, MacOS, and other UNIX-like systems. I recently ran into an interesting problem using openssl to convert a private key obtained from GoDaddy. Someone else used GoDaddy&amp;rsquo;s &amp;ldquo;wizard&amp;rdquo; interface to generate a certificate signing request (CSR) and private key, and saved the files on their Windows workstation. They purchased an SSL cert from GoDaddy, and shared all the files with me for installation on servers. GoDaddy saved the private key in the newer &lt;a href="https://en.wikipedia.org/wiki/PKCS_8"&gt;PKCS #8 format (pkcs8)&lt;/a&gt;, and one system required the key in the older &lt;a href="https://en.wikipedia.org/wiki/PKCS_1"&gt;PKCS #1 (pkcs1) format&lt;/a&gt;. It&amp;rsquo;s easy to tell the difference.&lt;/p&gt;</description></item><item><title>Nginx default user changed in RedHat/CentOS package nginx-1.16.1-1.el7</title><link>https://shocksolution.com/posts/nginx-default-user-changed-in-redhat-centoos-package/</link><pubDate>Tue, 12 Nov 2019 02:58:34 +0000</pubDate><guid>https://shocksolution.com/posts/nginx-default-user-changed-in-redhat-centoos-package/</guid><description>&lt;p&gt;The &lt;a href="https://centos.pkgs.org/7/epel-x86_64/nginx-1.16.1-1.el7.x86_64.rpm.html"&gt;latest Nginx rpm (nginx-1.16.1-1.el7) from EPEL&lt;/a&gt; for CentOS/Redhat is a &lt;a href="https://bugzilla.redhat.com/show_bug.cgi?id=1750857"&gt;fairly major update, from version 1.12 to 1.16, and includes some very important fixes to address multiple CVE&lt;/a&gt;s. There is another small but critical change in the latest RPM that isn&amp;rsquo;t mentioned in the bug report. RedHat had configured nginx to run as user &amp;ldquo;apache&amp;rdquo; in past releases, but in the EPEL release on 19 October 2019, the configuration was changed to run as user &amp;ldquo;nginx&amp;rdquo;. If you ran &amp;ldquo;yum upgrade&amp;rdquo; recently (which you really need to do on a regular basis) on any system with nginx installed, you probably have a system that is affected.&lt;/p&gt;</description></item><item><title>Another Reason to Enable Private IP Addresses on Google Cloud SQL</title><link>https://shocksolution.com/posts/another-reason-to-enable-private-ip-addresses-on-google-cloud-sql/</link><pubDate>Wed, 26 Jun 2019 18:16:22 +0000</pubDate><guid>https://shocksolution.com/posts/another-reason-to-enable-private-ip-addresses-on-google-cloud-sql/</guid><description>&lt;p&gt;Google Cloud SQL recently introduced the capability for an instance to have an IP address within the private address space of your VPC network. Previously, all Cloud SQL instances had IP addresses within the address space of the public Internet. Obviously, the public IP was a security and privacy concern, as well as a potential violation of some compliance and governance frameworks. Now, each instance may have a public IP, private IP, or both. There&amp;rsquo;s another potential benefit to using a private IP address: performance!&lt;/p&gt;</description></item><item><title>Managing remote servers with salt-ssh</title><link>https://shocksolution.com/posts/managing-remote-servers-with-salt-ssh/</link><pubDate>Mon, 13 May 2019 21:20:37 +0000</pubDate><guid>https://shocksolution.com/posts/managing-remote-servers-with-salt-ssh/</guid><description>&lt;p&gt;I love using &lt;a href="https://docs.saltstack.com/en/latest/"&gt;Salt&lt;/a&gt; to configure and manage servers at scale. Typically, a Salt master server manages an army of servers which are on the same private network. A salt-minion daemon runs on each client server and communicates with the master. Sometimes you need to manage a server which is outside of your internal network, such as a marketing web server running on a service like AWS LightSail, Linode, or Digital Ocean. That&amp;rsquo;s when salt-ssh comes in handy.&lt;/p&gt;</description></item><item><title>Find Last Login Time for Wordpress Users in the SQL Database</title><link>https://shocksolution.com/posts/find-last-login-time-for-wordpress-users-in-the-sql-database/</link><pubDate>Tue, 16 Apr 2019 16:49:21 +0000</pubDate><guid>https://shocksolution.com/posts/find-last-login-time-for-wordpress-users-in-the-sql-database/</guid><description>&lt;h2 id="question-what-are-the-timestamps-for-the-last-login-for-every-wordpress-user-in-this-wordpress-site"&gt;Question: What are the timestamps for the last login for every Wordpress user in this Wordpress site?&lt;/h2&gt;&#10;&lt;p&gt;Most answers say to install some plugin, and there are dozens that will show the date and time when each Wordpress user last logged in. However, plugins are a problem, because they always need to be kept up to date, and many plugins get abandoned. Now, you have a potential security problem. Also, this approach assumes that your Wordpress front-end is up and running; if your site has been hacked or accidentally broken, you need to go into the database to do some forensics.&lt;/p&gt;</description></item><item><title>Updating to Wordpress 5 on a Linux Host: Requesting FTP Credentials</title><link>https://shocksolution.com/posts/updating-wordpress-5-linux-host-ftp-credentials/</link><pubDate>Mon, 14 Jan 2019 17:10:43 +0000</pubDate><guid>https://shocksolution.com/posts/updating-wordpress-5-linux-host-ftp-credentials/</guid><description>&lt;p&gt;Wordpress 5 didn&amp;rsquo;t install automatically on sites hosted on my CentOS 7 Wordpress hosting server. That&amp;rsquo;s by design, because I&amp;rsquo;m selfish and I&amp;rsquo;d rather wait for a few bug-fix releases before making a major upgrade. When I chose to upgrade manually on a test site, Wordpress asked for my FTP credentials:&lt;/p&gt;&#10;&lt;figure class="ma0 w-75"&gt;&lt;img src="https://shocksolution.com/images/Wordpress-permission-problem-300x178.png"&#10;&#9;&#9;&#9;alt="Connection Information"&gt;&lt;figcaption&gt;&#10;&#9;&#9;&#9;&lt;p&gt;Connection Information: FTP credentials&lt;/p&gt;&#10;&#9;&#9;&lt;/figcaption&gt;&#10;&lt;/figure&gt;&#10;&#10;&lt;p&gt;If you&amp;rsquo;re hosting Wordpress on your own server, it &lt;strong&gt;does not need FTP credentials&lt;/strong&gt;. This page is a symptom of a permissions issue with the underlying server.  The web server (typically Apache) is unable to write the updated files to the Wordpress directory. From a security standpoint, this is actually a good thing. You generally don&amp;rsquo;t want to allow a public-facing service to make changes on your server. This problem occurs in other situations, such as configuring the WordFence plugin, so I&amp;rsquo;ve written a page devoted to &lt;a href="https://shocksolution.com/troubleshooting-wordpress-permissions-errors-on-linux-hosts/"&gt;troubleshooting Wordpress permissions on Linux hosts&lt;/a&gt;. That page describes how to fix the permissions issue without compromising the general security of your Wordpress host.&lt;/p&gt;</description></item><item><title>New Relic APM on Fedora/CentOS/RedHat with SELinux Enforcing: Solved</title><link>https://shocksolution.com/posts/new-relic-apm-on-fedora-centos-redhat-with-selinux-enforcing-solved/</link><pubDate>Thu, 14 Jun 2018 03:27:28 +0000</pubDate><guid>https://shocksolution.com/posts/new-relic-apm-on-fedora-centos-redhat-with-selinux-enforcing-solved/</guid><description>&lt;p&gt;I found the solution for getting the New Relic APM Agent to run on a CentOS 7 system with SELinux Enforcing. The only SELinux modification you have to make is to change the context of the log file directory &lt;strong&gt;/var/log/newrelic&lt;/strong&gt;. You can temporarily make these changes with the chcon command: [code lang=&amp;ldquo;bash&amp;rdquo;] chcon -R -t httpd_log_t /var/log/newrelic/ [/code] Kill any running instances of newrelic-daemon. If you&amp;rsquo;re using New Relic&amp;rsquo;s recommended default setup, make sure that the file /etc/newrelic/newrelic.cfg does &lt;strong&gt;not&lt;/strong&gt; exist. Verify that all required values in /etc/php.d/newrelic.ini are correct (especially the license key and the application name). Finally, restart httpd: [code lang=&amp;ldquo;bash&amp;rdquo;] systemctl restart httpd [/code] If that works, you should see output in both /var/log/newrelic/newrelic-daemon.log and /var/log/newrelic/php_agent.log. Now, make this file context change persistent, and verify the result: [code lang=&amp;ldquo;bash&amp;rdquo;] semanage fcontext &amp;ndash;add &amp;ndash;type httpd_log_t &amp;ldquo;/var/log/newrelic(/.*)?&amp;rdquo; restorecon -RF /var/log/newrelic/ ls -laZ /var/log/newrelic/ [/code] When you restart Apache, it spawns the newrelic-daemon processes, which communicate with APM via the socket file /tmp/.newrelic.sock. You really don&amp;rsquo;t want to run the newrelic-daemon processes via systemd if you can avoid it. The resulting process tree should look like this:&lt;/p&gt;</description></item><item><title>Configuring Laravel/Lumen applications to connect to SQL database sockets</title><link>https://shocksolution.com/posts/configuring-laravel-lumen-applications-to-connect-to-sql-database-sockets/</link><pubDate>Mon, 14 May 2018 18:58:47 +0000</pubDate><guid>https://shocksolution.com/posts/configuring-laravel-lumen-applications-to-connect-to-sql-database-sockets/</guid><description>&lt;p&gt;The Laravel/Lumen framework documentation does not explain how to connect an application to a database using UNIX sockets instead of a TCP-based network connection. I recently had to configure the &lt;a href="https://polrproject.org/"&gt;Polr URL shortener&lt;/a&gt; (built on the &lt;a href="https://lumen.laravel.com/"&gt;Lumen microframework&lt;/a&gt; by &lt;a href="https://laravel.com/"&gt;Laravel&lt;/a&gt;) to connect to Google Cloud SQL with a UNIX socket. Since all of Polr&amp;rsquo;s configuration takes place in the &lt;strong&gt;.env&lt;/strong&gt; file, and there is no environment variable that&amp;rsquo;s specific to database sockets, this took some research. I finally found the answer in an &lt;a href="https://stackoverflow.com/questions/29305502/php-artisan-migrate-with-mamp-and-unix-socket/39509268#39509268"&gt;obscure StackOverflow response&lt;/a&gt;. Previous TCP connection: [code] DB_HOST=some-server-name DB_PORT=3306 [/code] Socket-based SQL connection: [code] DB_HOST=localhost;unix_socket=/cloudsql/cloud-project-name:us-east1:sql-instance-name [/code] This approach will work with any UNIX socket; you just need to give it the absolute path to the socket.&lt;/p&gt;</description></item></channel></rss>